[Qemu-devel] [RFC PATCH v0] numa: API to lookup NUMA node by address

2015-05-07 Thread Bharata B Rao
Keep track of start and end address of each NUMA node in numa_info
structure so that lookup of node by address becomes easier. Add
an API numa_get_node() to lookup a node by address.

This is needed by sPAPR PowerPC to support
ibm,dynamic-reconfiguration-memory device tree node which is needed for
memory hotplug.

Signed-off-by: Bharata B Rao 
Reviewed-by: David Gibson 
---
This patch was earlier posted as part of sPAPR hotplug patchset here:
https://lists.gnu.org/archive/html/qemu-ppc/2015-04/msg00204.html

 include/sysemu/numa.h |  3 +++
 numa.c| 61 +++
 2 files changed, 64 insertions(+)

diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 6523b4d..19c0ba3 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -15,11 +15,14 @@ typedef struct node_info {
 DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
 struct HostMemoryBackend *node_memdev;
 bool present;
+ram_addr_t mem_start;
+ram_addr_t mem_end;
 } NodeInfo;
 extern NodeInfo numa_info[MAX_NODES];
 void parse_numa_opts(MachineClass *mc);
 void numa_post_machine_init(void);
 void query_numa_node_mem(uint64_t node_mem[]);
 extern QemuOptsList qemu_numa_opts;
+uint32_t numa_get_node(ram_addr_t addr, Error **errp);
 
 #endif
diff --git a/numa.c b/numa.c
index c975fb2..fdf333b 100644
--- a/numa.c
+++ b/numa.c
@@ -53,6 +53,63 @@ static int max_numa_nodeid; /* Highest specified NUMA node 
ID, plus one.
 int nb_numa_nodes;
 NodeInfo numa_info[MAX_NODES];
 
+/*
+ * Given an address, return the index of the NUMA node to which the
+ * address belongs to.
+ */
+uint32_t numa_get_node(ram_addr_t addr, Error **errp)
+{
+uint32_t i;
+MemoryDeviceInfoList *info_list = NULL;
+MemoryDeviceInfoList **prev = &info_list;
+MemoryDeviceInfoList *info;
+
+for (i = 0; i < nb_numa_nodes; i++) {
+if (addr >= numa_info[i].mem_start && addr < numa_info[i].mem_end) {
+return i;
+}
+}
+
+/*
+ * If this @addr falls under cold or hotplugged memory regions,
+ * check there too.
+ */
+qmp_pc_dimm_device_list(qdev_get_machine(), &prev);
+for (info = info_list; info; info = info->next) {
+MemoryDeviceInfo *value = info->value;
+
+if (value) {
+switch (value->kind) {
+case MEMORY_DEVICE_INFO_KIND_DIMM:
+if (addr >= value->dimm->addr &&
+addr < (value->dimm->addr + value->dimm->size)) {
+qapi_free_MemoryDeviceInfoList(info_list);
+return value->dimm->node;
+}
+break;
+default:
+break;
+}
+}
+}
+qapi_free_MemoryDeviceInfoList(info_list);
+error_setg(errp, "Address 0x" RAM_ADDR_FMT " doesn't belong to any "
+"NUMA node", addr);
+
+return -1;
+}
+
+static void numa_set_mem_address(int nodenr)
+{
+if (nodenr) {
+numa_info[nodenr].mem_start = numa_info[nodenr-1].mem_end;
+} else {
+numa_info[nodenr].mem_start = 0;
+}
+numa_info[nodenr].mem_end = numa_info[nodenr].mem_start +
+   numa_info[nodenr].node_mem;
+}
+
 static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error 
**errp)
 {
 uint16_t nodenr;
@@ -276,6 +333,10 @@ void parse_numa_opts(MachineClass *mc)
 }
 
 for (i = 0; i < nb_numa_nodes; i++) {
+numa_set_mem_address(i);
+}
+
+for (i = 0; i < nb_numa_nodes; i++) {
 if (!bitmap_empty(numa_info[i].node_cpu, MAX_CPUMASK_BITS)) {
 break;
 }
-- 
2.1.0




[Qemu-devel] [PATCH qemu] pseries: Update SLOF firmware image to qemu-slof-20150429

2015-05-07 Thread Alexey Kardashevskiy
The changelog is:
  > version: update to 20150429
  > pci: Use QEMU created PCI device nodes
  > usb: support 64-bit pci bars
  > pci: Support 64-bit address translation
  > pci: program correct bridge limit registers during probe
  > scsi: handle report-luns failure
  > Fix "key?" Forth word when using USB keyboards
  > Remove bulk.fs package
  > Include make.rules in the library Makefiles

Signed-off-by: Alexey Kardashevskiy 
---
 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 912192 -> 912720 bytes
 roms/SLOF|   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pc-bios/README b/pc-bios/README
index 63e7254..05cf042 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -17,7 +17,7 @@
 - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
   implementation for certain IBM POWER hardware.  The sources are at
   https://github.com/aik/SLOF, and the image currently in qemu is
-  built from git tag qemu-slof-20150313.
+  built from git tag qemu-slof-20150429.
 
 - sgabios (the Serial Graphics Adapter option ROM) provides a means for
   legacy x86 software to communicate with an attached serial console as
diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin
index 
ab72cba80c528aea2545974e9c717cee583c254c..0398ac67bc8d07410fe2ccc9d62c376ef3cf87c3
 100644
GIT binary patch
delta 88316
zcmce<34Bvk+CP5pZA(LekW}c#78ao(LRf^br>q4EgiY%*8n>CEz8YuH={Ssyj;~W0
zbW)^wsv<@Otcp%uTOCKEf>wvoxM6i%qPSE+iHceg=q`%kS`}u$V`F!Y;
zXMfIfp0nI@Z!Xb&Q)BN=4NWn=^3`}IXJ%#RXV(P!W!}4H;l1SeyieZERXw~9eQ?*D
zzEdxlI%Uealg>SV+IbTvPo4b8-@J{+DSvRern)A&C!FG%Fm<|n>huZjJ~^(1r@2nO
z@VCEPciE+`S+3u#TYqx0>L2G_{7lXzE{#97i(4sS=*x}Fdh%xIQ;ZBZRc7di^uvu6
znfi|z)0dr_;$*@vaPsRuIrPw4Bfqi1rXSGt7TTJluQ;*AyG=W5=EvIgv*v1%%9F9|4(Byt?jcxi9i0O
zeSgWd+CZ4Nep*g_E0y=s2OEHuz4VjxIBoBxPldntdg(RUZ~?rkA=Z+$2Y>aF)-
z!tA&-Dks&}^Phnf;_7(KEgE>`wBdItZt?g!|}1zo#iYf;RQhb0FOM
z-0%kW)|t>G2vH&7X|8XfSRZ|&Y5EEC`v~&&)-%a%H*I*DZ)hQ}T}qU9lE|F40NL4Y
z*T-kY&6c;=^ef1@bmpb%0$WXOIpD5K%?1gqu8?8BD
z+SDIG4yT^O+<{JEw9F}tRXR}}pf@=6kqld$`lLZ|=-R$GN7KH@)-+GEW@~#9aDRQP
zf3Bv{CAs=QYIf@OqWackA$05Yp3l%82#o>18$)qw$kj)3vUV1uQ*-qx{Cz*Z7o4C^
z?H`|IXjw30s<*zZY12yAwa^78=u>hbcK5oLndhNO5ToaLxY~7sJ{{`Q7UKIseCK8q
z_Y?4fexiAyLcM>+o(Zp0qMu$!|L&*vVX60|R6&0sy+*>2gnRpUXj5UHKAM&0=ZVY(
z@7_6U|eHS`_>lTPv
zlfbWsC3JaE)4puiH2;nuSW^~L!*IR8fr7|12YV|Ib}<)>
z=xtK`8jrA6nmkN&a$uOqOjP1Whv^GBg!#ku*<6Kw%?JB@OZ%({VG<9
zkFk`B=)98z6P}Ccu9Ng)mN1dePSP*eA0WpBy+8feSTT0Y7Hl3XR7~U*i5wm)D!=$-
zeY)(+0~o`tSEDbre_tLRgAsV+$$Fm@-rkoeI8h&&LVx91Q|B0TIHca=M2qH2=$oSt
zAR4ESXJ+#_{Yo?L@iKkm&GexM3+Ui@(K*QXcv|Y#hqGY7Eh_I(w|+Hu|IW+W$TLAd
z18Y##sDD*X$4pAT>FC;q33?9$%%%zY+`Rf$t}SjBmum28EwfZRR7;Mo;R||VP`V}y
z-uHWwn=I%*{8Kf#SHX-II|fAXA}zCeV|#n4_Vq^;ous=)V5&5iISzD2b63g8#`fc-
z+TlN$l2krPw(6y8KOFw#Qidejwr=YTiuA`$<
z^de(uA1autkJ7&~wvY(KeLUPZuHYnl6S+ocTr5
zXy6QytH2DwPt1fFqNNU_->rIJxY!@3|w;9jhhzSCFpw0SL9fzU&IDBEEGMb>aJ;_Fl#_{EDwcb&D^T+vkn^4Q?^#pZ}<
zY+j66DYs95o)I>zA5gjJN=+}-`(%;73H-gw_hM7eWki~1MNB;mu5HKylK^Ba$ToqHNJL+KFu(WjV51D-PJhuSNhF4`lmNX
z)(kch3n=~@{eJ!4#!VG^Ziewy*3H54!N$Q0DS9!;FEw6r39_zlcqDk{6y5mpSC2HE
z^{sBSu4~+Txqhu-e4N$jTd%*~r|8SJS+1Z~lk??azIv+}^JQZ8bK3RO_kEdYoOvy_
zjF{a6f7Z{i_pbL`du{aUJ&#nDYWw<7%bzjH?fV1s<~Ihe!}_gj6uBPh)+lzpevTd`
z_h0n8nfQ0i4vD{Dmelf?C$a90fRDX!By8&v~(4#l#|KjXyL?OI-
zdE@Sl`hPOuJ#rH!lmIo~1Pcyoy$M}*XXAB$!}TyO(AL*rYmBtj=*x?mrzz1DRyIS-)UQPP;J6{4}?tk(t$d1hxGv^AzsWp
z5tr7cYmT;|?KP#^vwKYYP-9-}x&w902mJw)4!^vUfZxa$r3XT^DU9o|$QQ*2f_zEG
z7xJyw9|+B8KM-te3F`}WBbr67I(
zBf4t)0b&3A|G@q~ovaEq+kt1;{*&LBrv4~Q{b|;_{eGHb(qZy8eaMMVFuSXXrygS(
zdzL0@DSDgU2=A3!^$+z(WBKiRu5L6Xt$n4&)%gkfu-Je>%WKH>+Z&&s;5ux#tQXle{yWc
zAg`yVw(D=}cQ$U>fr&+Lpu|qVFR1Ju?86!;aF4#tc=$we)a!r5G_|Q-4;v3TY3wsS
z3mRwMi#g7CaHYVG-mfpxvtHwH$n^kLYX1ZJwLQwr?llRIKdApTlWjbVa>jUj7!&Fa
z?ByOtH23tO;zuwHQ8$lZ9^Sc(S|33UnrOqL@Y_UfkLo`HBp%bBHtxKlvEgz34qbn%
z(buG(q33Ng_ncK1{-=^Fn{!jDZM(2B`hm@1^VS&{>_Mc34{^iQKhJr8DW4JL650&C7qP-@Mi?*ZdB)~nHMTG`
zLJKJI5|*)>FpOT-SLk~h125|{bWY5_^fU4{nM1(yr}l&x$z0)^dNvN+tB=aizoD~U
zL4wbERiB6bXyjF_ej87w(98Nvo9Dc0c)bDr7sG0rQ%sk{&`E!BhTAcNx?e-)-y+{@
zdOIiYb^R*cxE>SA8wl_^G~^9^jBfn7Ck=c{f6%!0^v1n!>6aN8ZZliZ>(`u1Wi9$-
zuCN|OH?)*$*O*=zjfcl;gbFPL)_|N6QTdOn&&#p_`A2e~ydVj!S
zX>XQU+Wys76hGLrm|W|7+Nl0V#EsJZ5!1KMy0U(3kj1z-=f9}5O`kpN@8+yO{%%df
z*=+=89KogSr~bt9ypYVe;UG?d+Vrc&JzT@IYtGin(UM(kV`=-rlkxp5rZcYWmuhEU
zNWPyiYpkU8Kk2ha-fyZ-b7>l8Q-`^*1-0O`F$Y^)*KuM_EnySn+l5k2{G{hEF56%;
zcB%yn2_57ass%V4)@{W?R=w^(?1nK1KGV6-3`SDVkRs-@PWDb*$zZ0dIVE)jG`-y
zfw&mW=|i{wT^~-apRrfj^(?Lb8C8k&{*2AXGO9R=YgX*dj_SY7S$QwJS=zpG0*yF^
zmD=|WU2qI%sV57v&s;D(=bunr`6m(S(stjS^yo2t{K?m_$QQFU+aEvCTt5xhY)ji8
z>eN5So2x$gSuTxdK1Pn?m@Y0P|8dNLk6~P|*3UJ!cC@}7ZkNMmI~GZ7RGC%t*kt2+
z!#J%cg`Vm;mIhv@_oQzOb}+qd*F^7Sw_j$CT4zu=+59H1{A&8^@x%Zl)nYQD$9*~YiIOI~AE
zhiIu2`W87~{lb;9g~GqIk=8@jV`dyZk~#=NhnzLzmX
zpViph%lJ^&|I}FD$C$3?&ilx;esxxb2&7~v9kv^P9J*GJGh01D8{+fUGR_+iPcW-~
zX?w}1jiJ6qhCX2e)4#xi@9}5V|6z3Y2wwb`w$Cv~!-lJQq-7ozZOW=I)fRr!xZ8oS
z(C>A*#(BofTj*%6F+gm_Tdx-GM5<=L(>V47<6(W+tWVj8VlHi;aU$dV&vV|580GW#
zg!>!6nCrfa_wxMw)+p^Yl^ukPMDq2-|a7J4RUbKSkj@y4EP5;4mY{IGCXK1{n+O
z<=?Zp>T|Ua#$bdR1{q_FgNNy?!NwGp*)rI;m2vkFSO)YDK_U*e(e5F}48

[Qemu-devel] [PATCH v4 0/4] spapr_pci: DT field fixes and PCI DT node creation in QEMU

2015-05-07 Thread Nikunj A Dadhania
The patch series creates PCI device tree(DT) nodes in QEMU. The new
hotplug code needs the device node creation in QEMU. While during
boot, nodes were created in SLOF. It makes more sense to consolidate
the code to one place for better maintainability.

Based on David's spapr-next 
https://github.com/dgibson/qemu/tree/spapr-next

Needs new slof.bin:
http://patchwork.ozlabs.org/patch/469303/

Also, patches for populating ibm,loc-code was getting very complicated
with use of RTAS/HCALL

Changelog V3:
* Dropped duplicate macro patches
* Squashed Michael's drc_index changes to enumeration patch
* Use common create routine for boottime and hotplug case
* Proper error handling not depending on g_assert
* Encode vfio loc-code if getting loc-code from host fails

Changelog V2:
 * Fix device tree for 64-bit encoding
 * Fix the class code, was failing xhci
 * Remove macro duplication
 * Fix DT fields generation for boot time device (Michael Roth)

Changelog v1:
 * Correct indent problems reported by checkpatch(David Gibson)
 * Declare sPAPRFDT structure as local (David Gibson)
 * Re-arrange code to avoid multiple indentation (Alexey Kardashevskiy)

Nikunj A Dadhania (4):
  spapr_pci: encode missing 64-bit memory address space
  spapr_pci: encode class code including Prog IF register
  spapr_pci: enumerate and add PCI device tree
  spapr_pci: populate ibm,loc-code

 hw/ppc/spapr_pci.c | 283 -
 1 file changed, 238 insertions(+), 45 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v4 1/4] spapr_pci: encode missing 64-bit memory address space

2015-05-07 Thread Nikunj A Dadhania
The properties reg/assigned-resources need to encode 64-bit memory
address space as part of phys.hi dword.

  00 if configuration space
  01 if IO region,
  10 if 32-bit MEM region
  11 if 64-bit MEM region

Signed-off-by: Nikunj A Dadhania 
Reviewed-by: Thomas Huth 
---
 hw/ppc/spapr_pci.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 4df3a33..ea1a092 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -786,7 +786,13 @@ typedef struct ResourceProps {
  * phys.hi = 0xYYZZ, where:
  *   0xYY = npt000ss
  *  |||   |
- *  |||   +-- space code: 1 if IO region, 2 if MEM region
+ *  |||   +-- space code
+ *  |||   |
+ *  |||   +  00 if configuration space
+ *  |||   +  01 if IO region,
+ *  |||   +  10 if 32-bit MEM region
+ *  |||   +  11 if 64-bit MEM region
+ *  |||
  *  ||+-- for non-relocatable IO: 1 if aliased
  *  ||for relocatable IO: 1 if below 64KB
  *  ||for MEM: 1 if below 1MB
@@ -846,6 +852,8 @@ static void populate_resource_props(PCIDevice *d, 
ResourceProps *rp)
 reg->phys_hi = cpu_to_be32(dev_id | b_(pci_bar(d, i)));
 if (d->io_regions[i].type & PCI_BASE_ADDRESS_SPACE_IO) {
 reg->phys_hi |= cpu_to_be32(b_ss(1));
+} else if (d->io_regions[i].type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+reg->phys_hi |= cpu_to_be32(b_ss(3));
 } else {
 reg->phys_hi |= cpu_to_be32(b_ss(2));
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 2/4] spapr_pci: encode class code including Prog IF register

2015-05-07 Thread Nikunj A Dadhania
Current code missed the Prog IF register. All Class Code, Subclass,
and Prog IF registers are needed to identify the accurate device type.

For example: USB controllers use the PROG IF for denoting: USB
FullSpeed, HighSpeed or SuperSpeed.

Signed-off-by: Nikunj A Dadhania 
Reviewed-by: Thomas Huth 
---
 hw/ppc/spapr_pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index ea1a092..8b02a3e 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -899,8 +899,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void 
*fdt, int offset,
 _FDT(fdt_setprop_cell(fdt, offset, "revision-id",
   pci_default_read_config(dev, PCI_REVISION_ID, 1)));
 _FDT(fdt_setprop_cell(fdt, offset, "class-code",
-  pci_default_read_config(dev, PCI_CLASS_DEVICE, 2)
-<< 8));
+  pci_default_read_config(dev, PCI_CLASS_PROG, 3)));
 if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) {
 _FDT(fdt_setprop_cell(fdt, offset, "interrupts",
  pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)));
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 3/4] spapr_pci: enumerate and add PCI device tree

2015-05-07 Thread Nikunj A Dadhania
All the PCI enumeration and device node creation was off-loaded to
SLOF. With PCI hotplug support, code needed to be added to add device
node. This creates multiple copy of the code one in SLOF and other in
hotplug code. To unify this, the patch adds the pci device node
creation in Qemu. For backward compatibility, a flag
"qemu,phb-enumerated" is added to the phb, suggesting to SLOF to not
do device node creation.

Signed-off-by: Nikunj A Dadhania 
[ Squashed Michael's drc_index changes ]
Signed-off-by: Michael Roth 
Signed-off-by: Nikunj A Dadhania 
---
 hw/ppc/spapr_pci.c | 188 ++---
 1 file changed, 150 insertions(+), 38 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 8b02a3e..12f1b9c 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -23,6 +23,7 @@
  * THE SOFTWARE.
  */
 #include "hw/hw.h"
+#include "hw/sysbus.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
@@ -35,6 +36,7 @@
 #include "qemu/error-report.h"
 #include "qapi/qmp/qerror.h"
 
+#include "hw/pci/pci_bridge.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/ppc/spapr_drc.h"
 #include "sysemu/device_tree.h"
@@ -742,6 +744,31 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void 
*opaque, int devfn)
 return &phb->iommu_as;
 }
 
+
+static sPAPRDRConnector *spapr_phb_get_pci_drc(sPAPRPHBState *phb,
+   PCIDevice *pdev)
+{
+uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev;
+return spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_PCI,
+(phb->index << 16) |
+(busnr << 8) |
+pdev->devfn);
+}
+
+static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
+PCIDevice *pdev)
+{
+sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
+sPAPRDRConnectorClass *drck;
+
+if (!drc) {
+return 0;
+}
+
+drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+return drck->get_index(drc);
+}
+
 /* Macros to operate with address in OF binding to PCI */
 #define b_x(x, p, l)(((x) & ((1<<(l))-1)) << (p))
 #define b_n(x)  b_x((x), 31, 1) /* 0 if relocatable */
@@ -879,12 +906,13 @@ static void populate_resource_props(PCIDevice *d, 
ResourceProps *rp)
 }
 
 static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
-   int phb_index, int drc_index,
+   sPAPRPHBState *sphb,
const char *drc_name)
 {
 ResourceProps rp;
 bool is_bridge = false;
 int pci_status;
+uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
 
 if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
 PCI_HEADER_TYPE_BRIDGE) {
@@ -945,8 +973,13 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
  * processed by OF beforehand
  */
 _FDT(fdt_setprop_string(fdt, offset, "name", "pci"));
-_FDT(fdt_setprop(fdt, offset, "ibm,loc-code", drc_name, strlen(drc_name)));
-_FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
+if (drc_name) {
+_FDT(fdt_setprop(fdt, offset, "ibm,loc-code", drc_name,
+ strlen(drc_name)));
+}
+if (drc_index) {
+_FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
+}
 
 _FDT(fdt_setprop_cell(fdt, offset, "#address-cells",
   RESOURCE_CELLS_ADDRESS));
@@ -963,30 +996,34 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
 return 0;
 }
 
+typedef struct sPAPRFDT {
+void *fdt;
+int node_off;
+sPAPRPHBState *sphb;
+} sPAPRFDT;
+
 /* create OF node for pci device and required OF DT properties */
-static void *spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
-   int drc_index, const char *drc_name,
-   int *dt_offset)
+static int spapr_create_pci_child_dt(PCIDevice *pdev, sPAPRFDT *p,
+ const char *drc_name)
 {
-void *fdt;
-int offset, ret, fdt_size;
-int slot = PCI_SLOT(dev->devfn);
-int func = PCI_FUNC(dev->devfn);
-char nodename[512];
+int offset, ret;
+char nodename[64];
+int slot = PCI_SLOT(pdev->devfn);
+int func = PCI_FUNC(pdev->devfn);
 
-fdt = create_device_tree(&fdt_size);
 if (func != 0) {
 sprintf(nodename, "pci@%d,%d", slot, func);
 } else {
 sprintf(nodename, "pci@%d", slot);
 }
-offset = fdt_add_subnode(fdt, 0, nodename);
-ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index,
+offset = fdt_add_subnode(p->fdt, p->node_off, nodename);
+ret = spapr_populate_pci_child_dt(pdev, p->fdt, offset, p->sphb,
  

[Qemu-devel] [PATCH v4 4/4] spapr_pci: populate ibm,loc-code

2015-05-07 Thread Nikunj A Dadhania
Each hardware instance has a platform unique location code.  The OF
device tree that describes a part of a hardware entity must include
the “ibm,loc-code” property with a value that represents the location
code for that hardware entity.

Populate ibm,loc-code.

1) PCI passthru devices need to identify with its own ibm,loc-code
   available on the host. In failure cases use:
   vfio_::.

2) Emulated devices encode as following:
   qemu_::.

Signed-off-by: Nikunj A Dadhania 
---
 hw/ppc/spapr_pci.c | 98 +++---
 1 file changed, 86 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 12f1b9c..d901007 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -769,6 +769,81 @@ static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState 
*phb,
 return drck->get_index(drc);
 }
 
+static bool spapr_phb_vfio_get_devspec_value(PCIDevice *pdev, char **value)
+{
+char *host;
+char path[PATH_MAX];
+
+host = object_property_get_str(OBJECT(pdev), "host", NULL);
+if (!host) {
+return false;
+}
+
+snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/devspec", host);
+g_free(host);
+
+return g_file_get_contents(path, value, NULL, NULL);
+}
+
+static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
+{
+char path[PATH_MAX], *buf = NULL;
+
+/* We have a vfio host bridge lets get the path. */
+if (!spapr_phb_vfio_get_devspec_value(pdev, &buf)) {
+return NULL;
+}
+
+snprintf(path, sizeof(path), "/proc/device-tree%s/ibm,loc-code", buf);
+g_free(buf);
+
+g_file_get_contents(path, &buf, NULL, NULL);
+return buf;
+}
+
+static char *spapr_phb_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
+{
+char *path = g_malloc(PATH_MAX);
+
+if (!path) {
+return NULL;
+}
+
+/*
+ * For non-vfio devices make up the location code out
+ * of the name, slot and function.
+ *
+ *   qemu_::.
+ */
+snprintf(path, PATH_MAX, "qemu_%s:%02d:%02d.%1d", pdev->name,
+ sphb->index, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+return path;
+}
+
+
+static char *spapr_ibm_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
+{
+if (object_dynamic_cast(OBJECT(pdev), "vfio-pci") != NULL) {
+char *buf = spapr_phb_vfio_get_loc_code(sphb, pdev);
+
+/*
+ * In case of failures reading the loc-code, make it up
+ * indicating a vfio device
+ */
+if (!buf) {
+buf = g_malloc(PATH_MAX);
+if (!buf) {
+return NULL;
+}
+snprintf(buf, PATH_MAX, "vfio_%s:%02d:%02d.%1d", pdev->name,
+ sphb->index, PCI_SLOT(pdev->devfn), 
PCI_FUNC(pdev->devfn));
+}
+return buf;
+} else {
+return spapr_phb_get_loc_code(sphb, pdev);
+}
+}
+
 /* Macros to operate with address in OF binding to PCI */
 #define b_x(x, p, l)(((x) & ((1<<(l))-1)) << (p))
 #define b_n(x)  b_x((x), 31, 1) /* 0 if relocatable */
@@ -906,12 +981,12 @@ static void populate_resource_props(PCIDevice *d, 
ResourceProps *rp)
 }
 
 static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
-   sPAPRPHBState *sphb,
-   const char *drc_name)
+   sPAPRPHBState *sphb)
 {
 ResourceProps rp;
 bool is_bridge = false;
 int pci_status;
+char *buf = NULL;
 uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
 
 if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
@@ -973,9 +1048,10 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
  * processed by OF beforehand
  */
 _FDT(fdt_setprop_string(fdt, offset, "name", "pci"));
-if (drc_name) {
-_FDT(fdt_setprop(fdt, offset, "ibm,loc-code", drc_name,
- strlen(drc_name)));
+buf = spapr_ibm_get_loc_code(sphb, dev);
+if (buf) {
+_FDT(fdt_setprop_string(fdt, offset, "ibm,loc-code", buf));
+g_free(buf);
 }
 if (drc_index) {
 _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
@@ -1003,8 +1079,7 @@ typedef struct sPAPRFDT {
 } sPAPRFDT;
 
 /* create OF node for pci device and required OF DT properties */
-static int spapr_create_pci_child_dt(PCIDevice *pdev, sPAPRFDT *p,
- const char *drc_name)
+static int spapr_create_pci_child_dt(PCIDevice *pdev, sPAPRFDT *p)
 {
 int offset, ret;
 char nodename[64];
@@ -1017,8 +1092,8 @@ static int spapr_create_pci_child_dt(PCIDevice *pdev, 
sPAPRFDT *p,
 sprintf(nodename, "pci@%d", slot);
 }
 offset = fdt_add_subnode(p->fdt, p->node_off, nodename);
-ret = spapr_populate_pci_child_dt(pdev, p->fdt, offset, p->sphb,
-  drc_name);
+
+ret = spa

[Qemu-devel] [PATCH] uhci: controller is halted after reset

2015-05-07 Thread Gerd Hoffmann
... and the status register should say so.

Fixes "usbus0: controller did not stop" error printed by freebsd.

Signed-off-by: Gerd Hoffmann 
---
 hw/usb/hcd-uhci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 64a7d87..3f0ed62 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -366,7 +366,7 @@ static void uhci_reset(DeviceState *dev)
 pci_conf[0x6a] = 0x01; /* usb clock */
 pci_conf[0x6b] = 0x00;
 s->cmd = 0;
-s->status = 0;
+s->status = UHCI_STS_HCHALTED;
 s->status2 = 0;
 s->intr = 0;
 s->fl_base_addr = 0;
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v6 01/17] Introduce stub routine cpu_desc_avail

2015-05-07 Thread Michael Mueller
On Wed, 6 May 2015 14:06:16 -0300
Eduardo Habkost  wrote:

> On Wed, May 06, 2015 at 06:23:05PM +0200, Michael Mueller wrote:
> > On Wed, 6 May 2015 08:23:32 -0300
> > Eduardo Habkost  wrote:
> [...]
> > > > > >cpudef_init();
> > > > > > 
> > > > > >if (cpu_model && cpu_desc_avail() && is_help_option(cpu_model)) {
> > > > > >list_cpus(stdout, &fprintf, cpu_model);
> > > > > >exit(0);
> > > > > >}
> > > > > > 
> > > > > > That is because the output does not solely depend on static 
> > > > > > definitions
> > > > > > but also on runtime context. Here the host machine type this 
> > > > > > instance of
> > > > > > QEMU is running on, at least for the KVM case.
> > > > > 
> > > > > Is this a required feature? I would prefer to have the main() code
> > > > > simple even if it means not having runnable information in "-cpu ?" by
> > > > > now (about possible ways to implement this without cpu_desc_avail(), 
> > > > > see
> > > > > below).
> > > > 
> > > > I think it is more than a desired feature because one might end up with 
> > > > a failed
> > > > CPU object instantiation although the help screen claims to CPU model 
> > > > to be valid. 
> > > 
> > > I think you are more likely to confuse users by not showing information
> > > on "-cpu ?" when -machine is not present. I believe most people use
> > > "-cpu ?" with no other arguments, to see what the QEMU binary is capable
> > > of.
> > 
> > I don't disagree with that, both cases are to some extend confusing...
> > But the accelerator makes a big difference and a tended user should really 
> > be aware
> > of that.
> > 
> > Also that TCG is the default:
> > 
> > $ ./s390x-softmmu/qemu-system-s390x -cpu ?
> > s390 host
> > 
> > And I don't see a way to make a user belief that all the defined CPU models 
> > are available to
> > a TCG user in the S390 case where most of the CPU facilities are not 
> > implemented.
> 
> Well, we could simply add a "KVM required" note (maybe just an asterisk beside
> the CPU model description). But maybe we have a reasonable alternative below:
> 
> > 
> > > 
> > > Anyway, whatever we decide to do, I believe we should start with
> > > something simple to get things working, and after that we can look for
> > > ways improve the help output with "runnable" info.
> > 
> > I don't see how to solve this without cpu_desc_avail() or some other 
> > comparable mechanism, the
> > aliases e.g. are also dynamic...
> 
> What bothers me in cpu_desc_avail() is that it depends on global state that is
> non-trivial (one needs to follow the whole KVM initialization path to find out
> if cpu_desc_avail() will be true or false).
> 
> We could instead simply skip the cpu_list() call unconditionally on s390. 
> e.g.:
> 
> target-s390x/cpu.h:
> /* Delete the existing cpu_list macro */
> 
> cpus.c:
> int list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
> {
> #if defined(cpu_list)
> cpu_list(f, cpu_fprintf);
> return 1;
> #else
> return 0;
> #endif
> }
> 
> vl.c:
> if (cpu_model && is_help_option(cpu_model)) {
> /* zero list_cpus() return value means "-cpu ?" will be
>  * handled later by machine initialization code */
> if (list_cpus(stdout, &fprintf, cpu_model)) {
> exit(0);
> }
> }

That approach is will do the job as well. I will prepare a patch for the next 
version.

Thanks!

> 
> [...]
> > > 
> > > About "-cpu ?": do we really want it to depend on -machine processing?
> > > Today, help output shows what the QEMU binary is capable of, not just
> > > what the host system and -machine option are capable of.
> > 
> > I think we have to take it into account because the available CPU models 
> > might
> > deviate substantially as in the case for S390 for KVM and TCG.
> 
> That's true, on s390 the set of available CPU models is very different on both
> cases. It breaks assumptions in the existing "-cpu ?" handling code in main().
> 
> >  
> > > 
> > > If we decide to change that assumption, let's do it in a generic way and
> > > not as a arch-specific hack. The options I see are:
> > 
> > welcome
> > 
> > > 
> > > 1) Continue with the current policy where "-cpu ?" does not depend on
> > >-machine arguments, and show all CPU models on "-cpu ?".
> > > 2) Deciding that, yes, it is OK to make "-cpu ?" depend on -machine
> > >arguments, and move the list_cpus() call after machine initialization
> > >inside generic main() code for all arches.
> > >2.1) We could delay the list_cpus() call inside main() on all cases.
> > >2.2) We could delay the list_cpus() call inside main() only if
> > > an explicit -machine option is present.
> > > 
> > > I prefer (1) and my second choice would be (2.2), but the main point is
> > > that none of the options above require making s390 special and
> > > introducing cpu_desc_avail().
> > 
> > My take here is 2.1 because omitting option -mach

Re: [Qemu-devel] [PATCH RFC V2 4/4] Add virtv2 machine that uses GIC-500

2015-05-07 Thread Shlomo Pongratz
On Thursday, May 7, 2015, Pavel Fedin  wrote:

>  Hello!
>
>  Why do we need 'virt2' ? I am currently working on testing your
> implementation, and i try to use different approach. I see this as
> '-machine
> virt,gicv=N' option, where N is 2 or 3. Isn't it better than duplicating
> the
> whole virt.c code just for single different function ?
>
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
>
>
>
Hi Pavel,

Thank you for your comment, I might do it after solving the stability
issues.

Best regards,

S.P.


Re: [Qemu-devel] [PATCH v6 05/17] Add optional parameters to QMP command query-cpu-definitions

2015-05-07 Thread Michael Mueller
On Wed, 6 May 2015 09:42:26 -0300
Eduardo Habkost  wrote:

> On Mon, Apr 27, 2015 at 04:53:19PM +0200, Michael Mueller wrote:
> [...]
> > diff --git a/qapi-schema.json b/qapi-schema.json
> > index 215a7bc..285b2d3 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -2536,21 +2536,43 @@
> >  #
> >  # @name: the name of the CPU definition
> >  #
> > +# @default: #optional true if cpu model is the default,
> > +#   omitted if false (since 2.4)
> 
> Maybe we should clarify that it is the default in the machine provided
> as argument to query-cpu-definitions?
> 
> > +#
> > +# @runnable: #optional true if cpu model is runnable,
> > +#omitted if false (since 2.4)
> 
> Maybe we should clarify that it means the CPU model is runnable using
> the machine+accel combination provided as arguments to
> query-cpu-definitions?

I will extend the comments accordingly.

> 
> (See also my question about the meaning of runnable when machine is
> omitted, in my reply to patch 15/17).
> 
> > +#
> > +# @live-migration-safe: #optional true if cpu model represents a
> > +#   cpu model that is safely migratable
> > +#   omitted if false (since 2.4)
> > +#
> > +# @order: #optional order criterion
> > +#
> >  # Since: 1.2.0
> >  ##
> >  { 'type': 'CpuDefinitionInfo',
> > -  'data': { 'name': 'str' } }
> > +  'data': { 'name': 'str', '*is-default': 'bool', '*runnable': 'bool',
> > +'*live-migration-safe': 'bool', '*order': 'int' } }
> >  
> >  ##
> >  # @query-cpu-definitions:
> >  #
> > -# Return a list of supported virtual CPU definitions
> > +# Return a list of supported virtual CPU definitions. In context with the
> > +# optional parameters @machine and @accel the returned list contains
> > +# also information if the respective cpu definition is runnable or the
> > +# default to be used.
> > +#
> > +# @machine: #optional machine type (since 2.4)
> > +#
> > +# @accel: #optional accelerator id (since 2.4)
> >  #
> >  # Returns: a list of CpuDefInfo
> >  #
> >  # Since: 1.2.0
> >  ##
> > -{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
> > +{ 'command': 'query-cpu-definitions',
> > +  'data': { '*machine': 'str', '*accel': 'AccelId' },
> > +  'returns': ['CpuDefinitionInfo'] }
> >  
> 




Re: [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name()

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Now that the two functions are identical, we only need one of them,
> and we might as well give it a more descriptive name.  Basically,
> the function serves as the translation from a QAPI name into a
> (portion of a) C identifier, without regards to whether it is a
> variable or function name.
>
> Signed-off-by: Eric Blake 

Reviewed-by: Markus Armbruster 



Re: [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Continuing the string of cleanups for supporting downstream names
> containing '.', this patch focuses on ensuring c_type() can
> handle a downstream name.  This patch alone does not fix the
> places where generator output should be calling this function
> but was open-coding things instead, but it gets us a step closer.
>
> Note that we generate a List type for our builtins; the code has
> to make sure that ['int'] maps to 'intList' (and not 'q_intList'),
> and that a member with type 'int' still maps to the C type 'int';
> on the other hand, a member with a name of 'int' will still map
> to 'q_int' when going through c_name().  This patch had to teach

has to teach

> type_name() to special-case builtins, since it is used by
> c_list_type() which in turn feeds c_type().
>
> Signed-off-by: Eric Blake 
> ---
>  scripts/qapi.py | 17 +
>  1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index b9822c6..a1dfc85 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -769,6 +769,9 @@ def c_enum_const(type_name, const_name):
>
>  c_name_trans = string.maketrans('.-', '__')
>
> +# This function is used for converting the name portion of 'name':'type'
> +# into a valid C name, for use as a struct member or substring of a
> +# function name.

Do we use it only for "the name portion of 'name':'type'"?

I'd prefer a more conventional function comment, like

# Map @name to a valid C identifier.
# If @protect, avoid returning certain ticklish identifiers like C
# keywords by prepending "q_".
# 

>  def c_name(name, protect=True):
>  # ANSI X3J11/88-090, 3.1.1
>  c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
> @@ -800,13 +803,18 @@ def c_name(name, protect=True):
>  return "q_" + name
>  return name.translate(c_name_trans)
>
> +# This function is used for computing the C type of a 'member':['name'] 
> array.

Likewise:

# Map type @name to the C typedef name for the list of this type.

>  def c_list_type(name):
> -return '%sList' % name
> +return type_name(name) + 'List'
>
> +# This function is used for converting the type of 'member':'name' into a
> +# substring for use in C pointer types or function names.

Likewise:

# Map type @name to its C typedef name.
# 

Consider rename parameter @name, because it can either be a name string,
or a list containing a name string.  Same for the other functions.
Perhaps in a separate patch for easier review.

>  def type_name(name):
>  if type(name) == list:
>  return c_list_type(name[0])
> -return name
> +if name in builtin_types.keys():
> +return name
> +return c_name(name)

Together with the change to c_list_type(), this changes type_name() as
follows:

* Name FOO becomes c_name(FOO) instead of FOO, except when FOO is the
  name of a built-in type.  Bug fix when FOO contains '.' or '-' or is
  a ticklish identifier other than a built-in type.

* List of FOO becomes c_name(FOO) + "List" instead of FOOList.  Bug fix
  when FOO contains '.' or '-'.  Not a bug fix when ticklish FOO becomes
  q_FOO, but improves consistency with the element type's C name then.

Correct?

>
>  def add_name(name, info, meta, implicit = False):
>  global all_names
> @@ -864,6 +872,7 @@ def is_enum(name):
>
>  eatspace = '\033EATSPACE.'
>
> +# This function is used for computing the full C type of 'member':'name'.
>  # A special suffix is added in c_type() for pointer types, and it's
>  # stripped in mcgen(). So please notice this when you check the return
>  # value of c_type() outside mcgen().

Likewise:

# Map type @name to its C type expression.
# If @is_param, const-qualify the string type.
# 
# A special suffix...

> @@ -888,13 +897,13 @@ def c_type(name, is_param=False):
>  elif type(name) == list:
>  return '%s *%s' % (c_list_type(name[0]), eatspace)
>  elif is_enum(name):
> -return name
> +return c_name(name)
>  elif name == None or len(name) == 0:
>  return 'void'

Aside: len(name) == 0 is a lame way to test name == "".
Aside^2: I wonder whether we ever pass that.

>  elif name in events:
>  return '%sEvent *%s' % (camel_case(name), eatspace)
>  else:
> -return '%s *%s' % (name, eatspace)
> +return '%s *%s' % (c_name(name), eatspace)

I figure the else is for complex types.  If that's correct, we should
perhaps add a comment.

>
>  def is_c_ptr(name):
>  suffix = "*" + eatspace

Together with the change to c_list_type(), this changes c_type() as
follows:

* Enum FOO becomes c_name(FOO) instead of FOO.  Bug fix when FOO
  contains '.' or '-' or is a ticklish identifier.

* Complex type FOO becomes c_name(FOO) + "*" instead of FOO *.  Bug fix
  when FOO contains '.' or '-' or is a ticklish identifier.

* List of FOO becomes c_name(FOO) + "List *" instead of FOOList *.  Bug
  fix when FOO contains '.' or '-'.  Not a bug fix when ticklish

Re: [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Enhance the testsuite to cover a downstream enum type and enum
> string.  Update the generator to mangle the enum name in the
> appropriate places.  The code for generating list visitors must
> be careful how it mangles names for enum lists differently than
> code for builtin type lists.
>
> Signed-off-by: Eric Blake 

One-liner test addition uncovers about a dozen bugs.

Reviewed-by: Markus Armbruster 



Re: [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Enhance the testsuite to cover downstream structs, including struct
> members and base structs.  Update the generator to mangle the
> struct names in the appropriate places.
>
> Signed-off-by: Eric Blake 

Reviewed-by: Markus Armbruster 



Re: [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Enhance the testsuite to cover downstream simple unions, including
> when a union branch is a downstream name.  Update the generator to
> mangle the union names in the appropriate places.
>
> Signed-off-by: Eric Blake 

Reviewed-by: Markus Armbruster 



Re: [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Enhance the testsuite to cover downstream alternates, including
> whether the branch name or type is downstream.  Update the
> generator to mangle alternate names in the appropriate places.
>
> Signed-off-by: Eric Blake 

Reviewed-by: Markus Armbruster 



Re: [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Enhance the testsuite to cover downstream flat unions, including
> the base type, discriminator name and type, and branch name and
> type.  Update the generator to mangle the union names in the
> appropriate places.
>
> Signed-off-by: Eric Blake 

Reviewed-by: Markus Armbruster 



[Qemu-devel] [PATCH RFC v8 3/7] qemu-iotests: s390x: fix test 041

2015-05-07 Thread Bo Tu
From: Xiao Guang Chen 

There is no 'ide-cd' device defined on s390 platform, so
test_medium_not_found() test should be skipped.

Reviewed-by: Max Reitz 
Reviewed-by: Michael Mueller 
Signed-off-by: Xiao Guang Chen 
---
 tests/qemu-iotests/041 | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 59a8f73..c6abe3c 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -197,6 +197,9 @@ class TestSingleDrive(ImageMirroringTestCase):
 'target image does not match source after mirroring')
 
 def test_medium_not_found(self):
+if iotests.qemu_default_machine != 'pc':
+return
+
 result = self.vm.qmp('drive-mirror', device='ide1-cd0', sync='full',
  target=target_img)
 self.assert_qmp(result, 'error/class', 'GenericError')
@@ -867,6 +870,9 @@ class TestRepairQuorum(ImageMirroringTestCase):
 if not self.has_quorum():
 return
 
+if iotests.qemu_default_machine != 'pc':
+return
+
 result = self.vm.qmp('drive-mirror', device='ide1-cd0', sync='full',
  node_name='repair0',
  replaces='img1',
-- 
2.3.0




[Qemu-devel] [PATCH RFC v8 7/7] qemu-iotests: s390x: fix test 130

2015-05-07 Thread Bo Tu
The default device id of hard disk on the s390 platform is "virtio0"
which differs to the "ide0-hd0" for the x86 platform. Setting id in
the drive definition, ie:"qemu -drive id=testdisk", will be the same
on all platforms.

Signed-off-by: Bo Tu 
---
 tests/qemu-iotests/130 | 8 
 tests/qemu-iotests/130.out | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
index bc26247..9209992 100755
--- a/tests/qemu-iotests/130
+++ b/tests/qemu-iotests/130
@@ -59,8 +59,8 @@ echo
 # bdrv_make_empty() involves a header update for qcow2
 
 # Test that a backing file isn't written
-_launch_qemu -drive file="$TEST_IMG",backing.file.filename="$TEST_IMG.base"
-_send_qemu_cmd $QEMU_HANDLE "commit ide0-hd0" "(qemu)"
+_launch_qemu -drive 
id=testdisk,file="$TEST_IMG",backing.file.filename="$TEST_IMG.base"
+_send_qemu_cmd $QEMU_HANDLE "commit testdisk" "(qemu)"
 _send_qemu_cmd $QEMU_HANDLE '' '(qemu)'
 _cleanup_qemu
 _img_info | _filter_img_info
@@ -68,8 +68,8 @@ _img_info | _filter_img_info
 # Make sure that if there was a backing file that was just overridden on the
 # command line, that backing file is retained, with the right format
 _make_test_img -F raw -b "$TEST_IMG.orig" 64M
-_launch_qemu -drive 
file="$TEST_IMG",backing.file.filename="$TEST_IMG.base",backing.driver=$IMGFMT
-_send_qemu_cmd $QEMU_HANDLE "commit ide0-hd0" "(qemu)"
+_launch_qemu -drive 
id=testdisk,file="$TEST_IMG",backing.file.filename="$TEST_IMG.base",backing.driver=$IMGFMT
+_send_qemu_cmd $QEMU_HANDLE "commit testdisk" "(qemu)"
 _send_qemu_cmd $QEMU_HANDLE '' '(qemu)'
 _cleanup_qemu
 _img_info | _filter_img_info
diff --git a/tests/qemu-iotests/130.out b/tests/qemu-iotests/130.out
index ea68b5d..9ec9d2a 100644
--- a/tests/qemu-iotests/130.out
+++ b/tests/qemu-iotests/130.out
@@ -9,14 +9,14 @@ virtual size: 64M (67108864 bytes)
 === HMP commit ===
 
 QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) 
ccocomcommcommicommitcommit
 commit icommit 
idcommit 
idecommit 
ide0commit 
ide0-commit 
ide0-hcommit 
ide0-hdcommit ide0-hd0
+(qemu) 
ccocomcommcommicommitcommit
 commit tcommit 
tecommit 
tescommit 
testcommit 
testdcommit 
testdicommit 
testdiscommit testdisk
 (qemu) 
 image: TEST_DIR/t.IMGFMT
 file format: IMGFMT
 virtual size: 64M (67108864 bytes)
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
backing_file='TEST_DIR/t.IMGFMT.orig' backing_fmt='raw'
 QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) 
ccocomcommcommicommitcommit
 commit icommit 
idcommit 
idecommit 
ide0commit 
ide0-commit 
ide0-hcommit 
ide0-hdcommit ide0-hd0
+(qemu) 
ccocomcommcommicommitcommit
 commit tcommit 
tecommit 
tescommit 
testcommit 
testdcommit 
testdicommit 
testdiscommit testdisk
 (qemu) 
 image: TEST_DIR/t.IMGFMT
 file format: IMGFMT
-- 
2.3.0




[Qemu-devel] [PATCH RFC v8 1/7] qemu-iotests: qemu machine type support

2015-05-07 Thread Bo Tu
From: Xiao Guang Chen 

This patch adds qemu machine type support to the io test suite.
Based on the qemu default machine type and alias of the default machine type
the reference output file can now vary from the default to a machine specific
output file if necessary. When using a machine specific reference file if the
default machine has an alias then use the alias as the output file name
otherwise use the default machine name as the output file name.

Reviewed-by: Max Reitz 
Reviewed-by: Michael Mueller 
Signed-off-by: Xiao Guang Chen 
---
 tests/qemu-iotests/check | 5 +
 tests/qemu-iotests/common.config | 9 +
 tests/qemu-iotests/iotests.py| 1 +
 3 files changed, 15 insertions(+)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index baeae80..22b2e63 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -324,6 +324,11 @@ do
 fi
 
 reference="$source_iotests/$seq.out"
+reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
+if [ -f "$reference_machine" ]; then
+reference="$reference_machine"
+fi
+
 if [ "$CACHEMODE" = "none" ]; then
 [ -f "$source_iotests/$seq.out.nocache" ] && 
reference="$source_iotests/$seq.out.nocache"
 fi
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index a1973ad..0288cb1 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -107,6 +107,15 @@ export QEMU=$QEMU_PROG
 export QEMU_IMG=$QEMU_IMG_PROG
 export QEMU_IO="$QEMU_IO_PROG $QEMU_IO_OPTIONS"
 export QEMU_NBD=$QEMU_NBD_PROG
+default_machine=$($QEMU -machine \? | awk '/(default)/{print $1}')
+default_alias_machine=$($QEMU -machine \? |\
+awk -v var_default_machine="$default_machine"\)\
+'{if ($(NF-2)=="(alias"&&$(NF-1)=="of"&&$(NF)==var_default_machine){print 
$1}}')
+if [ ! -z "$default_alias_machine" ]; then
+default_machine="$default_alias_machine"
+fi
+
+export QEMU_DEFAULT_MACHINE="$default_machine"
 
 [ -f /etc/qemu-iotest.config ]   && . /etc/qemu-iotest.config
 
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index e93e623..6a670c6 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -42,6 +42,7 @@ imgproto = os.environ.get('IMGPROTO', 'file')
 test_dir = os.environ.get('TEST_DIR', '/var/tmp')
 output_dir = os.environ.get('OUTPUT_DIR', '.')
 cachemode = os.environ.get('CACHEMODE')
+qemu_default_machine = os.environ.get('QEMU_DEFAULT_MACHINE')
 
 socket_scm_helper = os.environ.get('SOCKET_SCM_HELPER', 'socket_scm_helper')
 
-- 
2.3.0




[Qemu-devel] [PATCH RFC v8 5/7] qemu-iotests: s390x: fix test 049

2015-05-07 Thread Bo Tu
when creating an image qemu-img enable us specifying the size of the
image using -o size=xx options. But when we specify an invalid size
such as a negtive size then different platform gives different result.

parse_option_size() function in util/qemu-option.c will be called to
parse the size, a cast was called in the function to cast the input
(saved as a double in the function) size to an unsigned int64 value,
when the input is a negtive value or exceeds the maximum of uint64, then
the result is undefined.

Language spec 6.3.1.4 Real floating and integers:
the result of this assignment/cast is undefined if the float is not
in the open interval (-1, U_MAX+1).

Signed-off-by: Bo Tu 
---
 tests/qemu-iotests/049.out | 10 --
 util/qemu-option.c |  4 
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 9f93666..b8790f9 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -95,17 +95,15 @@ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1024
 qemu-img: Image size must be less than 8 EiB!
 
 qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2
-qemu-img: qcow2 doesn't support shrinking images yet
-qemu-img: TEST_DIR/t.qcow2: Could not resize image: Operation not supported
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off 
cluster_size=65536 lazy_refcounts=off refcount_bits=16
+qemu-img: Parameter 'size' expects a non-negative number below 2^64
+qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
 
 qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k
 qemu-img: Image size must be less than 8 EiB!
 
 qemu-img create -f qcow2 -o size=-1k TEST_DIR/t.qcow2
-qemu-img: qcow2 doesn't support shrinking images yet
-qemu-img: TEST_DIR/t.qcow2: Could not resize image: Operation not supported
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off 
cluster_size=65536 lazy_refcounts=off refcount_bits=16
+qemu-img: Parameter 'size' expects a non-negative number below 2^64
+qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
 
 qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
 qemu-img: Invalid image size specified! You may use k, M, G, T, P or E 
suffixes for
diff --git a/util/qemu-option.c b/util/qemu-option.c
index fda4e5f..6e75698 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -179,6 +179,10 @@ void parse_option_size(const char *name, const char *value,
 
 if (value != NULL) {
 sizef = strtod(value, &postfix);
+if (sizef < 0 || sizef > UINT64_MAX) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a 
non-negative number below 2^64");
+return;
+}
 switch (*postfix) {
 case 'T':
 sizef *= 1024;
-- 
2.3.0




[Qemu-devel] [PATCH RFC v8 2/7] qemu-iotests: run qemu with -nodefaults and fix 067, 071, 081 and 087

2015-05-07 Thread Bo Tu
From: Xiao Guang Chen 

This patch fixes an io test suite issue that was introduced with the
commit c88930a6866e74953e931ae749781e98e486e5c8 'qemu-char: Permit only
a single "stdio" character device'. The option supresses the creation of
default devices such as the floopy and cdrom. Output files for test case
067, 071, 081 and 087 need to be updated to accommodate this change.
Use virtio-blk instead of virtio-blk-pci as the device driver for test case
067. For virtio-blk-pci is the same with virtio-blk as device driver but
other platform such as s390 may not recognize the virtio-blk-pci.

Reviewed-by: Max Reitz 
Reviewed-by: Michael Mueller 
Signed-off-by: Xiao Guang Chen 
---
 tests/qemu-iotests/067   |   8 +-
 tests/qemu-iotests/067.out   | 266 +--
 tests/qemu-iotests/071.out   |   4 -
 tests/qemu-iotests/081.out   |   2 -
 tests/qemu-iotests/087.out   |  12 --
 tests/qemu-iotests/common|   1 +
 tests/qemu-iotests/common.config |   2 +-
 tests/qemu-iotests/common.qemu   |   2 +-
 8 files changed, 8 insertions(+), 289 deletions(-)

diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067
index 83eefa3..3e9a053 100755
--- a/tests/qemu-iotests/067
+++ b/tests/qemu-iotests/067
@@ -59,7 +59,7 @@ echo
 echo === -drive/-device and device_del ===
 echo
 
-run_qemu -drive file=$TEST_IMG,format=$IMGFMT,if=none,id=disk -device 
virtio-blk-pci,drive=disk,id=virtio0 <"${fifo_out}" 
\
 2>&1 \
 <"${fifo_in}" &
-- 
2.3.0




[Qemu-devel] [PATCH RFC v8 4/7] qemu-iotests: s390x: fix test 055

2015-05-07 Thread Bo Tu
From: Xiao Guang Chen 

There is no 'ide-cd' device defined on s390 platform, so
test_medium_not_found() test should be skipped.

Reviewed-by: Max Reitz 
Reviewed-by: Michael Mueller 
Signed-off-by: Xiao Guang Chen 
---
 tests/qemu-iotests/055 | 9 +
 1 file changed, 9 insertions(+)

diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index 017a609..e6e0ac4 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -104,11 +104,17 @@ class TestSingleDrive(iotests.QMPTestCase):
 self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
 
 def test_medium_not_found(self):
+if iotests.qemu_default_machine != 'pc':
+return
+
 result = self.vm.qmp('drive-backup', device='ide1-cd0',
  target=target_img, sync='full')
 self.assert_qmp(result, 'error/class', 'GenericError')
 
 def test_medium_not_found_blockdev_backup(self):
+if iotests.qemu_default_machine != 'pc':
+return
+
 result = self.vm.qmp('blockdev-backup', device='ide1-cd0',
  target='drive1', sync='full')
 self.assert_qmp(result, 'error/class', 'GenericError')
@@ -323,6 +329,9 @@ class TestSingleTransaction(iotests.QMPTestCase):
 self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
 
 def do_test_medium_not_found(self, cmd, target):
+if iotests.qemu_default_machine != 'pc':
+return
+
 result = self.vm.qmp('transaction', actions=[{
 'type': cmd,
 'data': { 'device': 'ide1-cd0',
-- 
2.3.0




Re: [Qemu-devel] [PATCH v6 02/17] Add accelerator id and model name to CPUState

2015-05-07 Thread Michael Mueller
On Wed, 6 May 2015 08:41:50 -0300
Eduardo Habkost  wrote:

> On Wed, May 06, 2015 at 11:59:38AM +0200, Michael Mueller wrote:
> > On Tue, 5 May 2015 10:26:02 -0300
> > Eduardo Habkost  wrote:
> > 
> > > On Mon, Apr 27, 2015 at 04:53:16PM +0200, Michael Mueller wrote:
> > > > The patch defines ids per accelerator and adds the accel_id and
> > > > the model_name to the CPUState. The accel_id is initialized by
> > > > common code, the model name needs to be initialized by target
> > > > specific code.
> > > > 
> > > > Signed-off-by: Michael Mueller 
> > > > Acked-by: Christian Borntraeger 
> > > > ---
> > > >  include/qom/cpu.h |  5 +
> > > >  qapi-schema.json  |  9 +
> > > >  qom/cpu.c | 14 ++
> > > >  3 files changed, 28 insertions(+)
> > > > 
> > > > diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> > > > index 9dafb48..4ffc050 100644
> > > > --- a/include/qom/cpu.h
> > > > +++ b/include/qom/cpu.h
> > > > @@ -236,6 +236,8 @@ struct kvm_run;
> > > >   * @mem_io_pc: Host Program Counter at which the memory was accessed.
> > > >   * @mem_io_vaddr: Target virtual address at which the memory was 
> > > > accessed.
> > > >   * @kvm_fd: vCPU file descriptor for KVM.
> > > > + * @accel_id: accelerator id of this CPU.
> > > > + * @model_name: model name of this CPU
> > > >   *
> > > >   * State of one CPU core or thread.
> > > >   */
> > > > @@ -313,6 +315,9 @@ struct CPUState {
> > > > (absolute value) offset as small as possible.  This reduces code
> > > > size, especially for hosts without large memory offsets.  */
> > > >  volatile sig_atomic_t tcg_exit_req;
> > > > +
> > > > +AccelId accel_id;
> > > 
> > > This can be a AccelState pointer, set on initialization, because we have
> > > another user case for having a AccelState pointer: query-cpu-definition
> > > implementations may create temporary CPU objects with a different accel
> > > object to be able to probe for accel-specific data.
> > > 
> > > (The pointer may become a link QOM property later.)
> > > 
> > > 
> > > > +char *model_name;
> > > >  };
> > > >  
> > > >  QTAILQ_HEAD(CPUTailQ, CPUState);
> > > > diff --git a/qapi-schema.json b/qapi-schema.json
> > > > index ac9594d..540e520 100644
> > > > --- a/qapi-schema.json
> > > > +++ b/qapi-schema.json
> > > > @@ -2515,6 +2515,15 @@
> > > >  ##
> > > >  { 'command': 'query-machines', 'returns': ['MachineInfo'] }
> > > >  
> > > > +# @AccelId
> > > > +#
> > > > +# Defines accelerator ids
> > > > +#
> > > > +# Since: 2.4
> > > > +##
> > > > +{ 'enum': 'AccelId',
> > > > +  'data': ['qtest', 'tcg', 'kvm', 'xen'] }
> > > > +
> > > 
> > > Not sure if it is better to have an enum or simply a string here.
> > > 
> > > >  ##
> > > >  # @CpuDefinitionInfo:
> > > >  #
> > > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > > index 108bfa2..457afc7 100644
> > > > --- a/qom/cpu.c
> > > > +++ b/qom/cpu.c
> > > > @@ -67,6 +67,20 @@ CPUState *cpu_generic_init(const char *typename, 
> > > > const char *cpu_model)
> > > >  goto out;
> > > >  }
> > > >  
> > > > +if (tcg_enabled()) {
> > > > +cpu->accel_id = ACCEL_ID_TCG;
> > > > +} else if (kvm_enabled()) {
> > > > +cpu->accel_id = ACCEL_ID_KVM;
> > > > +}
> > > > +#ifdef CONFIG_XEN
> > > > +else if (xen_enabled()) {
> > > > +cpu->accel_id = ACCEL_ID_XEN;
> > > > +}
> > > > +#endif
> > > > +else {
> > > > +cpu->accel_id = ACCEL_ID_QTEST;
> > > > +}
> > > 
> > > You can simply use ACCEL_GET_CLASS(current_machine->accelerator)->name
> > > here. If we really want an enum, we can add an AccelId field to
> > > AccelClass, and initialize it properly on the accel class_init
> > > functions.
> > 
> > The AccelClass (ac = ACCEL_GET_CLASS(current_machine->accelerator) would be 
> > ok though.
> > That will allow to access the ac->accel_id (not yet there) at places where 
> > required.
> > 
> > I'm just not sure how to access current_machine here.
> 
> It is a global variable declared in hw/boards.h. But it makes sense only
> if !CONFIG_USER.
> 
> But I am starting to wonder if we shouldn't simply expose accel info as
> a /mmachine property, instead of per-CPU information. It may become
> per-CPU in the future, but right now we really don't support having
> multiple accelerators so why are we trying to pretend we do?
> 

That brings me back into the direction I was before with the proposed 
query-cpu-model
QMP call... but that's OK. In the end that holds true also for the cpu model 
name as
well...

> > 
> > > 
> > > CONFIG_USER may require some special code when returning the accelerator
> > > ID as "tcg" because IIRC it doesn't use the QOM accel classes (yet).
> > > 
> > > > +
> > > >  object_property_set_bool(OBJECT(cpu), true, "realized", &err);
> > > >  
> > > >  out:
> > > > -- 
> > > > 1.8.3.1
> > > > 
> > > 
> > 
> 




[Qemu-devel] [PATCH RFC v8 6/7] qemu-iotests: s390x: fix test 051

2015-05-07 Thread Bo Tu
The tests for device type "ide_cd" should only be tested for the pc
platform.
The default device id of hard disk on the s390 platform differs to that
of the x86 platform. A new variable device_id is defined and "virtio0"
set for the s390 platform. A x86 platform specific output file is also
needed.
A new filter was added to filter orphan warnings.

Signed-off-by: Bo Tu 
---
 tests/qemu-iotests/051   |  85 +---
 tests/qemu-iotests/051.out   | 158 +-
 tests/qemu-iotests/051.pc.out| 433 +++
 tests/qemu-iotests/common.filter |   7 +
 4 files changed, 550 insertions(+), 133 deletions(-)
 create mode 100644 tests/qemu-iotests/051.pc.out

diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 0360f37..f06ba78 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -102,7 +102,13 @@ echo
 echo === Device without drive ===
 echo
 
-run_qemu -device virtio-scsi-pci -device scsi-hd
+case "$QEMU_DEFAULT_MACHINE" in
+pc)
+   run_qemu -device virtio-scsi-pci -device scsi-hd
+   ;;
+*)
+   ;;
+esac
 
 echo
 echo === Overriding backing file ===
@@ -147,13 +153,19 @@ run_qemu -drive if=ide
 run_qemu -drive if=virtio
 run_qemu -drive if=scsi
 
-run_qemu -drive if=none,id=disk -device ide-cd,drive=disk
-run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
+case "$QEMU_DEFAULT_MACHINE" in
+pc)
+run_qemu -drive if=none,id=disk -device ide-cd,drive=disk
+run_qemu -drive if=none,id=disk -device lsi53c895a -device 
scsi-cd,drive=disk
 
-run_qemu -drive if=none,id=disk -device ide-drive,drive=disk
-run_qemu -drive if=none,id=disk -device ide-hd,drive=disk
-run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
-run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
+run_qemu -drive if=none,id=disk -device ide-drive,drive=disk
+run_qemu -drive if=none,id=disk -device ide-hd,drive=disk
+run_qemu -drive if=none,id=disk -device lsi53c895a -device 
scsi-disk,drive=disk
+run_qemu -drive if=none,id=disk -device lsi53c895a -device 
scsi-hd,drive=disk
+;;
+*)
+;;
+esac
 
 echo
 echo === Read-only ===
@@ -167,13 +179,19 @@ run_qemu -drive file="$TEST_IMG",if=ide,readonly=on
 run_qemu -drive file="$TEST_IMG",if=virtio,readonly=on
 run_qemu -drive file="$TEST_IMG",if=scsi,readonly=on
 
-run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
ide-cd,drive=disk
-run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
lsi53c895a -device scsi-cd,drive=disk
+case "$QEMU_DEFAULT_MACHINE" in
+pc)
+run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
ide-cd,drive=disk
+run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
lsi53c895a -device scsi-cd,drive=disk
 
-run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
ide-drive,drive=disk
-run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
ide-hd,drive=disk
-run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
lsi53c895a -device scsi-disk,drive=disk
-run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
lsi53c895a -device scsi-hd,drive=disk
+run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
ide-drive,drive=disk
+run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
ide-hd,drive=disk
+run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
lsi53c895a -device scsi-disk,drive=disk
+run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device 
lsi53c895a -device scsi-hd,drive=disk
+;;
+*)
+;;
+esac
 
 echo
 echo === Cache modes ===
@@ -182,12 +200,12 @@ echo
 # Cannot use the test image because cache=none might not work on the host FS
 # Use cdrom so that we won't get errors about missing media
 
-run_qemu -drive media=cdrom,cache=none
-run_qemu -drive media=cdrom,cache=directsync
-run_qemu -drive media=cdrom,cache=writeback
-run_qemu -drive media=cdrom,cache=writethrough
-run_qemu -drive media=cdrom,cache=unsafe
-run_qemu -drive media=cdrom,cache=invalid_value
+run_qemu -drive if=scsi,media=cdrom,cache=none
+run_qemu -drive if=scsi,media=cdrom,cache=directsync
+run_qemu -drive if=scsi,media=cdrom,cache=writeback
+run_qemu -drive if=scsi,media=cdrom,cache=writethrough
+run_qemu -drive if=scsi,media=cdrom,cache=unsafe
+run_qemu -drive if=scsi,media=cdrom,cache=invalid_value
 
 echo
 echo === Specifying the protocol layer ===
@@ -251,28 +269,37 @@ echo
 echo === Snapshot mode ===
 echo
 
+case "$QEMU_DEFAULT_MACHINE" in
+pc)
+device_id="ide0-hd0"
+;;
+s390)
+device_id="virtio0"
+;;
+esac
+
 $QEMU_IO -c "write -P 0x11 0 4k" "$TEST_IMG" | _filter_qemu_io
 
-echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive 
file="

[Qemu-devel] [PATCH RFC v8 0/7] Update tests/qemu-iotests failing cases for the s390 platform

2015-05-07 Thread Bo Tu
v8.
1.Modify error message in qemu-option.c when image size is invalid
2.Remove Reviewed-by statements if any functional changes in a new patch version
for test 049,051,130
3.Change patch subject for test 130
4.Add id definition for a drive which will work for all platforms in test 130
5.Disable virtio-scsi-pci for non-PCI systems in test 051

v7.
1. Add a pc specific output file for test 130.
2. A new variable device_id is defined in test 130 to support multiplatform. 
3. Update the output file for test 051 based on it's current output.
4. change util/qemu-option.c and test case 049, generate error message 
when image size is a negtive value or exceeds the maximum of uint64

v6.
1. Change the filter name from _filter_s390 to _filter_orphan.
2. Update the output file for tese case 081 because no default floopy and 
cd-rom.

v5:
1. Add a pc specific output file for test 051.
2. Add a filter to test case 051 to filter s390 specific warnings.
3. Check whether the machine type is pc or not rather than check whether the 
machine type 
is s390.
4. When using a machine specific reference file if the default machine has an 
alias then
use the alias as the output file name otherwise use the default machine name as 
the output
file name.

v4:
1. Generate all patches based on the latest master branch.
2. Rearrange patches

v3:
1. Fix a typo in v2.

v2:
1. Drop the patches for test 039 for it has been fixed in upstream.
2. Integrate patches for test 071, 067 and 087.
3. Keep the other patches.

v1:
1. updated the test suite to be default-machine-type-aware, from the previous 
platform-aware
2. created a new patch "qemu-iotests: run qemu with -nodefaults" to counterpart 
the impact from the commit:
c88930a6866e74953e931ae749781e98e486e5c8
qemu-char: Permit only a single "stdio" character device

When more than one is used, the terminal settings aren't restored
correctly on exit.  Fixable.  However, such usage makes no sense,
because the users race for input, so outlaw it instead.

If you want to connect multiple things to stdio, use the mux
chardev.
3. updated all the checking of platform name to the current machine name

Bo Tu (3):
  qemu-iotests: s390x: fix test 049
  qemu-iotests: s390x: fix test 051
  qemu-iotests: s390x: fix test 130

Xiao Guang Chen (4):
  qemu-iotests: qemu machine type support
  qemu-iotests: run qemu with -nodefaults and fix 067,071,081 and 087
  qemu-iotests: s390x: fix test 041
  qemu-iotests: s390x: fix test 055

 tests/qemu-iotests/041   |   6 +
 tests/qemu-iotests/049.out   |  10 +-
 tests/qemu-iotests/051   |  85 +---
 tests/qemu-iotests/051.out   | 158 +-
 tests/qemu-iotests/051.pc.out| 433 +++
 tests/qemu-iotests/055   |   9 +
 tests/qemu-iotests/067   |   8 +-
 tests/qemu-iotests/067.out   | 266 +---
 tests/qemu-iotests/071.out   |   4 -
 tests/qemu-iotests/081.out   |   2 -
 tests/qemu-iotests/087.out   |  12 --
 tests/qemu-iotests/130   |   8 +-
 tests/qemu-iotests/130.out   |   4 +-
 tests/qemu-iotests/check |   5 +
 tests/qemu-iotests/common|   1 +
 tests/qemu-iotests/common.config |  11 +-
 tests/qemu-iotests/common.filter |   7 +
 tests/qemu-iotests/common.qemu   |   2 +-
 tests/qemu-iotests/iotests.py|   1 +
 util/qemu-option.c   |   4 +
 20 files changed, 602 insertions(+), 434 deletions(-)
 create mode 100644 tests/qemu-iotests/051.pc.out

-- 
2.3.0




Re: [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands

2015-05-07 Thread Markus Armbruster
Eric Blake  writes:

> Enhance the testsuite to cover downstream events and commands.
> Events worked without more tweaks, but commands needed a few final
> updates in the generator to mangle names in the appropriate places.
> In making those tweaks, it was easier to drop type_visitor() and
> inline its actions instead.
>
> Signed-off-by: Eric Blake 

Reviewed-by: Markus Armbruster 



Re: [Qemu-devel] [PATCH v6 00/47] Postcopy implementation

2015-05-07 Thread Dr. David Alan Gilbert
* Li, Liang Z (liang.z...@intel.com) wrote:
> > > > > Thanks Dave, I will retry according to your suggestion.
> > > >
> > > > Did that work for you?
> > > >
> > >
> > > Yes, it works.
> > 
> > Great.
> > 
> > > Bye the way, I found that the source guest will resume after about 15
> > > minuets if there are some network errors happened during post copy. Is it
> > the expected behavior?
> > > And have you any plan about handing such errors?
> > 
> > Interesting; it shouldn't do that.  I think it's best for the source to 
> > stay in
> > paused following an error.  Were you driving it directly or via libvirt?
> > 
> 
> Drive it directly.

OK, thanks, I'll have a look at it.

Dave

> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH RFC V2 4/4] Add virtv2 machine that uses GIC-500

2015-05-07 Thread Pavel Fedin
 Hello!

➢ Thank you for your comment, I might do it after solving the stability issues.

 What kind of stability issues do you have ?
 You know, i was testing 64-bit qemu in TCG mode, and i have also seen weird 
behavior. The kernel just stops and waits until you hit any key on the console, 
then it continues. This happens if i try to use more than one CPU. This has to 
do with guest kernel version, in v4.1rc2 this is gone, while still present in 
v4.0rc1. Originally i discovered this issue on v3.19. So, perhaps it's some 
guest kernel flaw, having to do with interrupts.
 The first place where it is stuck is after initializing usbcore. After hitting 
enter it says "switching clocksource to..." (i don't remember) and goes on. 
After this it can stop like this again, in some random moment.
 Which kernel version do you use for guest ?

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia





Re: [Qemu-devel] [PATCH 1/4] spapr: Merge sPAPREnvironment into sPAPRMachineState

2015-05-07 Thread Thomas Huth
On Thu,  7 May 2015 13:57:01 +1000
David Gibson  wrote:

> The code for -machine pseries maintains a global sPAPREnvironment structure
> which keeps track of general state information about the guest platform.
> This predates the existence of the MachineState structure, but performs
> basically the same function.
> 
> Now that we have the generic MachineState, fold sPAPREnvironment into
> sPAPRMachineState, the pseries specific subclass of MachineState.
> 
> This is mostly a matter of search and replace, although a few places which
> relied on the global spapr variable are changed to find the structure via
> qdev_get_machine().
> 
> Signed-off-by: David Gibson 
> ---
>  hw/char/spapr_vty.c |  14 +-
>  hw/intc/xics.c  |  42 +++---
>  hw/intc/xics_kvm.c  |   2 +-
>  hw/net/spapr_llan.c |  20 +--
>  hw/nvram/spapr_nvram.c  |   8 +-
>  hw/ppc/spapr.c  | 339 
> +---
>  hw/ppc/spapr_events.c   |  37 ++---
>  hw/ppc/spapr_hcall.c|  44 +++---
>  hw/ppc/spapr_iommu.c|   8 +-
>  hw/ppc/spapr_pci.c  |  91 ++--
>  hw/ppc/spapr_rtas.c |  66 -
>  hw/ppc/spapr_rtc.c  |  12 +-
>  hw/ppc/spapr_vio.c  |  31 ++--
>  include/hw/pci-host/spapr.h |  12 +-
>  include/hw/ppc/spapr.h  |  33 +++--
>  include/hw/ppc/spapr_vio.h  |   6 +-
>  16 files changed, 391 insertions(+), 374 deletions(-)
> 
> diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
> index 4e464bd..5a27740 100644
> --- a/hw/char/spapr_vty.c
> +++ b/hw/char/spapr_vty.c
> @@ -74,7 +74,7 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error 
> **errp)
>  }
>  
>  /* Forward declaration */
> -static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr,
> +static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *sm,
>  target_ulong opcode, target_ulong *args)

Phew, this patch is really hugh, ... mainly just because of the
renaming. Could you maybe keep the "spapr" as parameter name everywhere
instead of "sm"? (i.e. use "sPAPRMachineState *spapr" as parameter?)
That should IMHO be fine, too, and it would decrease the size of the
patch drastically. (And it likely does not break other patches so badly
which are currently pending)

 Thomas



Re: [Qemu-devel] [Qemu-block] [PATCH 5/6] qcow2: use a hash to look for entries in the L2 cache

2015-05-07 Thread Alberto Garcia
On Wed 06 May 2015 06:42:30 PM CEST, Stefan Hajnoczi wrote:

>> By using a hash of the offset as the starting point, lookups are
>> faster and independent from the array size.
>> 
>> The hash is computed using the cluster number of the table, multiplied
>> by 4 to make it perform better when there are collisions.
> ...
>> +i = lookup_index = (offset / c->table_size * 4) % c->size;

> The hash function is very weak.  It's better than always starting with
> i=0 but mixes input bits very poorly.  Have you considered an integer
> hash function so that more input bits affect the output?
> http://burtleburtle.net/bob/hash/integer.html

I didn't try very hard to optimize the hash function because it doesn't
have a big impact, I just wanted something simple and a bit better than
i=0.

I did my tests with a disk image with preallocated metadata and a cache
size big enough for the whole disk. In that scenario I managed an
average of 2.5 comparisons per lookup with this function.

> Regarding collisions, the multiply-by-4 effectively reduces the hash
> space by a factor of 4.  This *increases* the chance of collisions in
> the hope that the extra slots will prevent chains from forming.

It does, but it keeps the average much lower (in my tests at least), it
went down from >100 to 2.5.

> Feel free to leave the hash function as-is, I don't think it's a huge
> issue either way.

I think I'll just leave it as-is for the time being, but thanks a lot
for your comments.

Berto



Re: [Qemu-devel] [PATCH RFC V2 4/4] Add virtv2 machine that uses GIC-500

2015-05-07 Thread Shlomo Pongratz
On Thursday, May 7, 2015, Pavel Fedin  wrote:

>  Hello!
>
> ➢ Thank you for your comment, I might do it after solving the stability
> issues.
>
>  What kind of stability issues do you have ?
>  You know, i was testing 64-bit qemu in TCG mode, and i have also seen
> weird behavior. The kernel just stops and waits until you hit any key on
> the console, then it continues. This happens if i try to use more than one
> CPU. This has to do with guest kernel version, in v4.1rc2 this is gone,
> while still present in v4.0rc1. Originally i discovered this issue on
> v3.19. So, perhaps it's some guest kernel flaw, having to do with
> interrupts.
>  The first place where it is stuck is after initializing usbcore. After
> hitting enter it says "switching clocksource to..." (i don't remember) and
> goes on. After this it can stop like this again, in some random moment.
>  Which kernel version do you use for guest ?
>
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
>
> Hi Pavel,

The stability issue is described in patch .
The issue is similar to what you have noticed.
The larger the number of smp cores it is more likely that the boot will get
stuck.
I've commuted this patch series as an RFC because of this issue.

Best regards,

S.P.


[Qemu-devel] [PATCH v6 00/22] Generate ACPI v5.1 tables and expose them to guest over fw_cfg on ARM

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

This patch series generate seven ACPI tables for machine virt on ARM.
The set of generated tables are:
- RSDP
- RSDT
- MADT
- GTDT
- FADT
- DSDT
- MCFG (For PCIe host bridge)

These tables are created dynamically using the function of aml-build.c,
taking into account the needed information passed from the virt machine
model. When the generation is finalized, it use fw_cfg to expose the
tables to guest.

You can fetch this from following repo:
http://git.linaro.org/people/shannon.zhao/qemu.git  ACPI_ARM_v6

And this patchset refers to Alexander Spyridakis's patches which are
sent to qemu-devel mailing list before.
http://lists.gnu.org/archive/html/qemu-devel/2014-10/msg03987.html

Thanks to Laszlo's work on UEFI (ArmVirtualizationQemu) supporting
downloading ACPI tables over fw_cfg, we now can use ACPI in VM.

Now upstream kernel applies ACPI patchset, so we can boot it with ACPI,
while we need to apply patches[1] to make tty work, patch[2] to make
virtio-mmio work and apply patch[3] and the relevant patches to make PCI
devices works, e.g. virtio-net-pci, e1000.
On the other hand, you can directly use the Fedora Linux kernel from
following address:
https://git.fedorahosted.org/cgit/kernel-arm64.git/log/?h=devel

I've done test with following VM:
xp, windows2008, sles11 on X86
upstream kernel and Fedora Linux kernel on ARM64

In addtion, dump all the acpi tables, use iasl -d *.dat to convert to
*.asl and use iasl -tc *.asl to compile them to *.hex. No error appears.

[1] http://git.linaro.org/leg/acpi/acpi.git/shortlog/refs/heads/acpi-sbsa
[2] 
http://git.linaro.org/leg/acpi/acpi.git/commit/57acba56d55e3fb521fd6ce767446459ef7a4943
[3] 
https://git.fedorahosted.org/cgit/kernel-arm64.git/commit/?h=devel&id=8cf58cbe94b982b680229e5b164231eea0ca2d11

changes since v5:
  * Fix table version (Igor)
  * only create CPU device objects for present CPUs (Igor)
  * drop madt->local_apic_address and madt->flags (Igor)
  * adjust implementation of ToUUID macro (Igor)
  * Fix aml_buffer() (Michael & Igor)
  * Fix aml_not()  

changes since v4:
  * use trace_* instead of DPRINTF (Igor & Alex)
  * use standard QEMU style for structs (Michael)
  * add "-no-acpi" option support for arm
  * use extractNN for bits operation (Alex)
  * use AmlReadAndWrite enum for rw flags (Igor)
  * s/uint64_t/uint32_t/ (Igor)
  * use enum for interrupt flag (Igor)
  * simplify aml_device use in DSDT (Alex)
  * share RSDT table generating code with x86 (Igor)
  * remove unnecessary 1 in MCFG table generating code (Alex & Peter)
  * use string for ToUUID macro (Igor)
  * aml_or and aml_and use two args (Igor)
  * add comments on UUID (Michael)
  * change PCI MMIO region non-cacheable (Peter)
  * fix wrong io map (Peter)
  * add several reviewed-by's from Alex, thanks

changes since v3:
  * rebase on upstream qemu
  * fix _HID of CPU (Heyi Guo)
  * Add PCIe host bridge

changes since v2:
  * rebase on Igor Mammedov's new branch ASL_API_v3
  * use rsdt instead of xsdt according to Igor Mammedov's suggestion

changes since v1:
  * fix bug found by Laszlo
  * move common helpers into dedictated file and change generating
table order according to Igor's comments
  * fix copyright and function name according to Michael's comments

Shannon Zhao (22):
  hw/i386: Move ACPI header definitions in an arch-independent location
  hw/i386/acpi-build: move generic acpi building helpers into dedictated
file
  hw/arm/virt-acpi-build: Basic framework for building ACPI tables on
ARM
  hw/acpi/aml-build: Add aml_memory32_fixed() term
  hw/acpi/aml-build: Add aml_interrupt() term
  hw/arm/virt-acpi-build: Generation of DSDT table for virt devices
  hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers
  hw/arm/virt-acpi-build: Generate MADT table
  hw/arm/virt-acpi-build: Generate GTDT table
  hw/arm/virt-acpi-build: Generate RSDT table
  hw/arm/virt-acpi-build: Generate RSDP table
  hw/arm/virt-acpi-build: Add PCIe info and generate MCFG table
  hw/acpi/aml-build: Make aml_buffer() definition consistent with the
spec
  hw/acpi/aml-build: Add ToUUID macro
  hw/acpi/aml-build: Add aml_or() term
  hw/acpi/aml-build: Add aml_lnot() term
  hw/acpi/aml-build: Add aml_else() term
  hw/acpi/aml-build: Add aml_create_dword_field() term
  hw/acpi/aml-build: Add aml_dword_io() term
  hw/acpi/aml-build: Add Unicode macro
  hw/arm/virt-acpi-build: Add PCIe controller in ACPI DSDT table
  hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables

 default-configs/arm-softmmu.mak  |   1 +
 default-configs/i386-softmmu.mak |   3 +
 default-configs/mips-softmmu.mak |   3 +
 default-configs/mips64-softmmu.mak   |   3 +
 default-configs/mips64el-softmmu.mak |   3 +
 default-configs/mipsel-softmmu.mak   |   3 +
 default-configs/x86_64-softmmu.mak   |   3 +
 hw/acpi/Makefile.objs|   5 +-
 hw/acpi/aml-build.c  | 270 ++-
 hw/arm/Makefile.objs |   1 +
 

[Qemu-devel] [PATCH v6 08/22] hw/arm/virt-acpi-build: Generate MADT table

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

MADT describes GIC enabled ARM platforms. The GICC and GICD
subtables are used to define the GIC regions.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
Reviewed-by: Alex Bennée 
---
 hw/arm/virt-acpi-build.c | 57 
 include/hw/acpi/acpi-defs.h  | 38 ++-
 include/hw/arm/virt-acpi-build.h |  3 +++
 3 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 05e1057..2383700 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -42,6 +42,20 @@
 #include "hw/hw.h"
 #include "hw/acpi/aml-build.h"
 
+typedef struct VirtAcpiCpuInfo {
+DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT);
+} VirtAcpiCpuInfo;
+
+static void virt_acpi_get_cpu_info(VirtAcpiCpuInfo *cpuinfo)
+{
+CPUState *cpu;
+
+memset(cpuinfo->found_cpus, 0, sizeof cpuinfo->found_cpus);
+CPU_FOREACH(cpu) {
+set_bit(cpu->cpu_index, cpuinfo->found_cpus);
+}
+}
+
 static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
 {
 uint16_t i;
@@ -138,6 +152,43 @@ static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
*virtio_mmio_memmap,
 }
 }
 
+/* MADT */
+static void
+build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
+   VirtAcpiCpuInfo *cpuinfo)
+{
+int madt_start = table_data->len;
+const struct AcpiMadtInfo *info = guest_info->madt_info;
+AcpiMultipleApicTable *madt;
+AcpiMadtGenericDistributor *gicd;
+int i;
+
+madt = acpi_data_push(table_data, sizeof *madt);
+
+for (i = 0; i < guest_info->smp_cpus; i++) {
+AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
+ sizeof *gicc);
+gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
+gicc->length = sizeof(*gicc);
+gicc->base_address = info->gic_cpu_memmap->addr;
+gicc->cpu_interface_number = i;
+gicc->arm_mpidr = i;
+gicc->uid = i;
+if (test_bit(i, cpuinfo->found_cpus)) {
+gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
+}
+}
+
+gicd = acpi_data_push(table_data, sizeof *gicd);
+gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
+gicd->length = sizeof(*gicd);
+gicd->base_address = info->gic_dist_memmap->addr;
+
+build_header(linker, table_data,
+ (void *)(table_data->data + madt_start), "APIC",
+ table_data->len - madt_start, 5);
+}
+
 /* FADT */
 static void
 build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
@@ -207,8 +258,11 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 {
 GArray *table_offsets;
 unsigned dsdt;
+VirtAcpiCpuInfo cpuinfo;
 GArray *tables_blob = tables->table_data;
 
+virt_acpi_get_cpu_info(&cpuinfo);
+
 table_offsets = g_array_new(false, true /* clear */,
 sizeof(uint32_t));
 
@@ -233,6 +287,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables_blob);
 build_fadt(tables_blob, tables->linker, dsdt);
 
+acpi_add_table(table_offsets, tables_blob);
+build_madt(tables_blob, tables->linker, guest_info, &cpuinfo);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index f29772e..778042d 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -236,7 +236,13 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
 #define ACPI_APIC_IO_SAPIC   6
 #define ACPI_APIC_LOCAL_SAPIC7
 #define ACPI_APIC_XRUPT_SOURCE   8
-#define ACPI_APIC_RESERVED   9   /* 9 and greater are reserved 
*/
+#define ACPI_APIC_LOCAL_X2APIC   9
+#define ACPI_APIC_LOCAL_X2APIC_NMI  10
+#define ACPI_APIC_GENERIC_INTERRUPT 11
+#define ACPI_APIC_GENERIC_DISTRIBUTOR   12
+#define ACPI_APIC_GENERIC_MSI_FRAME 13
+#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
+#define ACPI_APIC_RESERVED  15   /* 15 and greater are reserved */
 
 /*
  * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
@@ -284,6 +290,36 @@ struct AcpiMadtLocalNmi {
 } QEMU_PACKED;
 typedef struct AcpiMadtLocalNmi AcpiMadtLocalNmi;
 
+struct AcpiMadtGenericInterrupt {
+ACPI_SUB_HEADER_DEF
+uint16_t reserved;
+uint32_t cpu_interface_number;
+uint32_t uid;
+uint32_t flags;
+uint32_t parking_version;
+uint32_t performance_interrupt;
+uint64_t parked_address;
+uint64_t base_address;
+uint64_t gicv_base_address;
+uint64_t gich_base_address;
+uint32_t vgic_interrupt;
+uint64_t gicr_base_address;
+uint64_t arm_mpidr;
+} QEMU_PACKED;
+
+typedef struct AcpiMadtGenericInterrupt AcpiMadtGenericInterrupt;
+
+struct AcpiMadtGenericDistributor {
+ACPI_SUB_HEADER_DEF
+uint16_

[Qemu-devel] [PATCH v6 09/22] hw/arm/virt-acpi-build: Generate GTDT table

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

ACPI v5.1 defines GTDT for ARM devices as a place to describe timer
related information in the system. The Arch Timer interrupts must
be provided for GTDT.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c| 30 ++
 include/hw/acpi/acpi-defs.h | 37 +
 2 files changed, 67 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 2383700..efdd8dd 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -152,6 +152,33 @@ static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
*virtio_mmio_memmap,
 }
 }
 
+/* GTDT */
+static void
+build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+{
+int gtdt_start = table_data->len;
+const struct AcpiGtdtInfo *info = guest_info->gtdt_info;
+AcpiGenericTimerTable *gtdt;
+
+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 = info->timer_s_el1;
+gtdt->secure_el1_flags = ACPI_EDGE_SENSITIVE;
+
+gtdt->non_secure_el1_interrupt = info->timer_ns_el1;
+gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE;
+
+gtdt->virtual_timer_interrupt = info->timer_virt;
+gtdt->virtual_timer_flags = ACPI_EDGE_SENSITIVE;
+
+gtdt->non_secure_el2_interrupt = info->timer_ns_el2;
+gtdt->non_secure_el2_flags = ACPI_EDGE_SENSITIVE;
+
+build_header(linker, table_data,
+ (void *)(table_data->data + gtdt_start), "GTDT",
+ table_data->len - gtdt_start, 5);
+}
+
 /* MADT */
 static void
 build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
@@ -290,6 +317,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables_blob);
 build_madt(tables_blob, tables->linker, guest_info, &cpuinfo);
 
+acpi_add_table(table_offsets, tables_blob);
+build_gtdt(tables_blob, tables->linker, guest_info);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 778042d..b722d61 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -321,6 +321,43 @@ struct AcpiMadtGenericDistributor {
 typedef struct AcpiMadtGenericDistributor AcpiMadtGenericDistributor;
 
 /*
+ * 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)
+
+struct AcpiGenericTimerTable {
+ACPI_TABLE_HEADER_DEF
+uint64_t counter_block_addresss;
+uint32_t reserved;
+uint32_t secure_el1_interrupt;
+uint32_t secure_el1_flags;
+uint32_t non_secure_el1_interrupt;
+uint32_t non_secure_el1_flags;
+uint32_t virtual_timer_interrupt;
+uint32_t virtual_timer_flags;
+uint32_t non_secure_el2_interrupt;
+uint32_t non_secure_el2_flags;
+uint64_t counter_read_block_address;
+uint32_t platform_timer_count;
+uint32_t platform_timer_offset;
+} QEMU_PACKED;
+typedef struct AcpiGenericTimerTable AcpiGenericTimerTable;
+
+/*
  * HPET Description Table
  */
 struct Acpi20Hpet {
-- 
2.0.4





[Qemu-devel] [PATCH v6 15/22] hw/acpi/aml-build: Add aml_or() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 10 ++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index d9c9876..bda99bf 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -455,6 +455,16 @@ Aml *aml_and(Aml *arg1, Aml *arg2)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
+Aml *aml_or(Aml *arg1, Aml *arg2)
+{
+Aml *var = aml_opcode(0x7D /* OrOp */);
+aml_append(var, arg1);
+aml_append(var, arg2);
+build_append_byte(var->buf, 0x00 /* NullNameOp */);
+return var;
+}
+
 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
 Aml *aml_notify(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 7399f04..a039ffe 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -202,6 +202,7 @@ Aml *aml_int(const uint64_t val);
 Aml *aml_arg(int pos);
 Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
+Aml *aml_or(Aml *arg1, Aml *arg2);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
 Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
-- 
2.0.4





[Qemu-devel] [PATCH v6 04/22] hw/acpi/aml-build: Add aml_memory32_fixed() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Add aml_memory32_fixed() for describing device mmio region in resource template.
These can be used to generating DSDT table for ACPI on ARM.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 27 +++
 include/hw/acpi/aml-build.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 8d01959..61407b7 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -26,6 +26,7 @@
 #include 
 #include "hw/acpi/aml-build.h"
 #include "qemu/bswap.h"
+#include "qemu/bitops.h"
 #include "hw/acpi/bios-linker-loader.h"
 
 static GArray *build_alloc_array(void)
@@ -505,6 +506,32 @@ Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, 
Aml *arg3, Aml *arg4)
 return var;
 }
 
+/*
+ * ACPI 1.0: 6.4.3.4 Memory32Fixed (Memory Resource Descriptor Macro)
+ */
+Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
+AmlReadAndWrite read_and_write)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
+build_append_byte(var->buf, 9); /* Length, bits[7:0] value = 9 */
+build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */
+build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
+
+/* Range base address */
+build_append_byte(var->buf, extract32(addr, 0, 8)); /* bits[7:0] */
+build_append_byte(var->buf, extract32(addr, 8, 8)); /* bits[15:8] */
+build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
+build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
+
+/* Range length */
+build_append_byte(var->buf, extract32(size, 0, 8)); /* bits[7:0] */
+build_append_byte(var->buf, extract32(size, 8, 8)); /* bits[15:8] */
+build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
+build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
+return var;
+}
+
 /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
 uint8_t aln, uint8_t len)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 1705001..154823b 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -162,6 +162,8 @@ Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
 Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3);
 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4);
+Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
+AmlReadAndWrite read_and_write);
 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
 uint8_t aln, uint8_t len);
 Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
-- 
2.0.4





[Qemu-devel] [PATCH v6 02/22] hw/i386/acpi-build: move generic acpi building helpers into dedictated file

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Move generic acpi building helpers into dedictated file and this
can be shared with other machines.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 58 ++
 hw/i386/acpi-build.c| 77 -
 include/hw/acpi/aml-build.h | 29 +
 3 files changed, 87 insertions(+), 77 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index d7945f6..8d01959 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -26,6 +26,7 @@
 #include 
 #include "hw/acpi/aml-build.h"
 #include "qemu/bswap.h"
+#include "hw/acpi/bios-linker-loader.h"
 
 static GArray *build_alloc_array(void)
 {
@@ -891,3 +892,60 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
  dec, addr_gran, addr_min, addr_max,
  addr_trans, len, flags);
 }
+
+void
+build_header(GArray *linker, GArray *table_data,
+ AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
+{
+memcpy(&h->signature, sig, 4);
+h->length = cpu_to_le32(len);
+h->revision = rev;
+memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
+memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
+memcpy(h->oem_table_id + 4, sig, 4);
+h->oem_revision = cpu_to_le32(1);
+memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
+h->asl_compiler_revision = cpu_to_le32(1);
+h->checksum = 0;
+/* Checksum to be filled in by Guest linker */
+bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
+table_data->data, h, len, &h->checksum);
+}
+
+void *acpi_data_push(GArray *table_data, unsigned size)
+{
+unsigned off = table_data->len;
+g_array_set_size(table_data, off + size);
+return table_data->data + off;
+}
+
+unsigned acpi_data_len(GArray *table)
+{
+#if GLIB_CHECK_VERSION(2, 22, 0)
+assert(g_array_get_element_size(table) == 1);
+#endif
+return table->len;
+}
+
+void acpi_add_table(GArray *table_offsets, GArray *table_data)
+{
+uint32_t offset = cpu_to_le32(table_data->len);
+g_array_append_val(table_offsets, offset);
+}
+
+void acpi_build_tables_init(AcpiBuildTables *tables)
+{
+tables->rsdp = g_array_new(false, true /* clear */, 1);
+tables->table_data = g_array_new(false, true /* clear */, 1);
+tables->tcpalog = g_array_new(false, true /* clear */, 1);
+tables->linker = bios_linker_loader_init();
+}
+
+void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
+{
+void *linker_data = bios_linker_loader_cleanup(tables->linker);
+g_free(linker_data);
+g_array_free(tables->rsdp, true);
+g_array_free(tables->table_data, true);
+g_array_free(tables->tcpalog, mfre);
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 5515837..2d6e5a2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -68,9 +68,6 @@
 
 #define ACPI_BUILD_TABLE_SIZE 0x2
 
-/* Reserve RAM space for tables: add another order of magnitude. */
-#define ACPI_BUILD_TABLE_MAX_SIZE 0x20
-
 /* #define DEBUG_ACPI_BUILD */
 #ifdef DEBUG_ACPI_BUILD
 #define ACPI_BUILD_DPRINTF(fmt, ...)\
@@ -265,51 +262,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
 NULL);
 }
 
-#define ACPI_BUILD_APPNAME  "Bochs"
-#define ACPI_BUILD_APPNAME6 "BOCHS "
-#define ACPI_BUILD_APPNAME4 "BXPC"
-
-#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
-#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
-#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
-
-static void
-build_header(GArray *linker, GArray *table_data,
- AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
-{
-memcpy(&h->signature, sig, 4);
-h->length = cpu_to_le32(len);
-h->revision = rev;
-memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
-memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
-memcpy(h->oem_table_id + 4, sig, 4);
-h->oem_revision = cpu_to_le32(1);
-memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
-h->asl_compiler_revision = cpu_to_le32(1);
-h->checksum = 0;
-/* Checksum to be filled in by Guest linker */
-bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
-table_data->data, h, len, &h->checksum);
-}
-
-/* End here */
 #define ACPI_PORT_SMI_CMD   0x00b2 /* TODO: this is APM_CNT_IOPORT */
 
-static inline void *acpi_data_push(GArray *table_data, unsigned size)
-{
-unsigned off = table_data->len;
-g_array_set_size(table_data, off + size);
-return table_data->data + off;
-}
-
-static unsigned acpi_data_len(GArray *table)
-{
-#if GLIB_CHECK_VERSION(2, 22, 0)
-assert(g_array_get_element_size(table) == 1);
-#endif
-return table->len;
-}
-
 static void acpi_align_size(GArray *blob, unsigned align)
 {
 /* Align size to multiple of given size. This reduces the chance
@@ -318,12 +272,6

[Qemu-devel] [PATCH v6 10/22] hw/arm/virt-acpi-build: Generate RSDT table

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

RSDT points to other tables FADT, MADT, GTDT. This code is shared with x86.

Here we still use RSDT as UEFI puts ACPI tables below 4G address space,
and UEFI ignore the RSDT or XSDT.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 24 
 hw/arm/virt-acpi-build.c|  3 +++
 hw/i386/acpi-build.c| 24 
 include/hw/acpi/aml-build.h |  2 ++
 4 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index babe4d6..b99bb13 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1004,3 +1004,27 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, 
bool mfre)
 g_array_free(tables->table_data, true);
 g_array_free(tables->tcpalog, mfre);
 }
+
+/* Build rsdt table */
+void
+build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
+{
+AcpiRsdtDescriptorRev1 *rsdt;
+size_t rsdt_len;
+int i;
+const int table_data_len = (sizeof(uint32_t) * table_offsets->len);
+
+rsdt_len = sizeof(*rsdt) + table_data_len;
+rsdt = acpi_data_push(table_data, rsdt_len);
+memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len);
+for (i = 0; i < table_offsets->len; ++i) {
+/* rsdt->table_offset_entry to be filled by Guest linker */
+bios_linker_loader_add_pointer(linker,
+   ACPI_BUILD_TABLE_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   table_data, 
&rsdt->table_offset_entry[i],
+   sizeof(uint32_t));
+}
+build_header(linker, table_data,
+ (void *)rsdt, "RSDT", rsdt_len, 1);
+}
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index efdd8dd..401e634 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -320,6 +320,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables_blob);
 build_gtdt(tables_blob, tables->linker, guest_info);
 
+/* RSDT is pointed to by RSDP */
+build_rsdt(tables_blob, tables->linker, table_offsets);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 2d6e5a2..b753f08 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1193,30 +1193,6 @@ build_dsdt(GArray *table_data, GArray *linker, 
AcpiMiscInfo *misc)
  misc->dsdt_size, 1);
 }
 
-/* Build final rsdt table */
-static void
-build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
-{
-AcpiRsdtDescriptorRev1 *rsdt;
-size_t rsdt_len;
-int i;
-
-rsdt_len = sizeof(*rsdt) + sizeof(uint32_t) * table_offsets->len;
-rsdt = acpi_data_push(table_data, rsdt_len);
-memcpy(rsdt->table_offset_entry, table_offsets->data,
-   sizeof(uint32_t) * table_offsets->len);
-for (i = 0; i < table_offsets->len; ++i) {
-/* rsdt->table_offset_entry to be filled by Guest linker */
-bios_linker_loader_add_pointer(linker,
-   ACPI_BUILD_TABLE_FILE,
-   ACPI_BUILD_TABLE_FILE,
-   table_data, 
&rsdt->table_offset_entry[i],
-   sizeof(uint32_t));
-}
-build_header(linker, table_data,
- (void *)rsdt, "RSDT", rsdt_len, 1);
-}
-
 static GArray *
 build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 5b60744..d1b9fe7 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -268,5 +268,7 @@ unsigned acpi_data_len(GArray *table);
 void acpi_add_table(GArray *table_offsets, GArray *table_data);
 void acpi_build_tables_init(AcpiBuildTables *tables);
 void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre);
+void
+build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets);
 
 #endif
-- 
2.0.4





[Qemu-devel] [PATCH v6 03/22] hw/arm/virt-acpi-build: Basic framework for building ACPI tables on ARM

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Introduce a preliminary framework in virt-acpi-build.c with the main
ACPI build functions. It exposes the generated ACPI contents to
guest over fw_cfg.

The required ACPI v5.1 tables for ARM are:
- RSDP: Initial table that points to XSDT
- RSDT: Points to FADT GTDT MADT tables
- FADT: Generic information about the machine
- GTDT: Generic timer description table
- MADT: Multiple APIC description table
- DSDT: Holds all information about system devices/peripherals, pointed by FADT

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/arm/Makefile.objs |   1 +
 hw/arm/virt-acpi-build.c | 184 +++
 include/hw/arm/virt-acpi-build.h |  70 +++
 qemu-options.hx  |   2 +-
 trace-events |   3 +
 5 files changed, 259 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/virt-acpi-build.c
 create mode 100644 include/hw/arm/virt-acpi-build.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2577f68..a1bfb19 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
+obj-$(CONFIG_ACPI) += virt-acpi-build.o
 obj-y += netduino2.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
new file mode 100644
index 000..960206d
--- /dev/null
+++ b/hw/arm/virt-acpi-build.c
@@ -0,0 +1,184 @@
+/* Support for generating ACPI tables and passing them to Guests
+ *
+ * ARM virt ACPI generation
+ *
+ * Copyright (C) 2008-2010  Kevin O'Connor 
+ * Copyright (C) 2006 Fabrice Bellard
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin 
+ *
+ * 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 of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "hw/arm/virt-acpi-build.h"
+#include 
+#include 
+#include "qemu-common.h"
+#include "qemu/bitmap.h"
+#include "trace.h"
+#include "qom/cpu.h"
+#include "target-arm/cpu.h"
+#include "hw/acpi/acpi-defs.h"
+#include "hw/acpi/acpi.h"
+#include "hw/nvram/fw_cfg.h"
+#include "hw/acpi/bios-linker-loader.h"
+#include "hw/loader.h"
+#include "hw/hw.h"
+#include "hw/acpi/aml-build.h"
+
+typedef
+struct AcpiBuildState {
+/* Copy of table in RAM (for patching). */
+MemoryRegion *table_mr;
+MemoryRegion *rsdp_mr;
+MemoryRegion *linker_mr;
+/* Is table patched? */
+uint8_t patched;
+VirtGuestInfo *guest_info;
+} AcpiBuildState;
+
+static
+void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
+{
+GArray *table_offsets;
+
+table_offsets = g_array_new(false, true /* clear */,
+sizeof(uint32_t));
+
+bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
+ 64, false /* high memory */);
+
+/*
+ * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
+ * RSDP
+ * RSDT
+ * FADT
+ * GTDT
+ * MADT
+ * DSDT
+ */
+
+/* Cleanup memory that's no longer used. */
+g_array_free(table_offsets, true);
+}
+
+static void acpi_ram_update(MemoryRegion *mr, GArray *data)
+{
+uint32_t size = acpi_data_len(data);
+
+/* Make sure RAM size is correct - in case it got changed
+ * e.g. by migration */
+memory_region_ram_resize(mr, size, &error_abort);
+
+memcpy(memory_region_get_ram_ptr(mr), data->data, size);
+memory_region_set_dirty(mr, 0, size);
+}
+
+static void virt_acpi_build_update(void *build_opaque, uint32_t offset)
+{
+AcpiBuildState *build_state = build_opaque;
+AcpiBuildTables tables;
+
+/* No state to update or already patched? Nothing to do. */
+if (!build_state || build_state->patched) {
+return;
+}
+build_state->patched = 1;
+
+acpi_build_tables_init(&tables);
+
+virt_acpi_build(build_state->guest_info, &tables);
+
+acpi_ram_update(build_state->table_mr, tables.table_data);
+acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
+acpi_ram_update(build_state->linker_mr, tables.linker);
+
+
+acpi_build_tables_cleanup(&tables, true);
+}
+

[Qemu-devel] [PATCH v6 07/22] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

In the case of mach virt, it is used to set the Hardware Reduced bit
and enable PSCI SMP booting through HVC. So ignore FACS and FADT
points to DSDT.

Update the header definitions for FADT taking into account the new
additions of ACPI v5.1 in `include/hw/acpi/acpi-defs.h`

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c|  31 
 include/hw/acpi/acpi-defs.h | 115 ++--
 2 files changed, 109 insertions(+), 37 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 1a00ad7..05e1057 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -138,6 +138,31 @@ static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
*virtio_mmio_memmap,
 }
 }
 
+/* FADT */
+static void
+build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
+{
+AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+
+/* 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));
+
+/* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
+fadt->minor_revision = 0x1;
+
+fadt->dsdt = cpu_to_le32(dsdt);
+/* DSDT address to be filled by Guest linker */
+bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   table_data, &fadt->dsdt,
+   sizeof fadt->dsdt);
+
+build_header(linker, table_data,
+ (void *)fadt, "FACP", sizeof(*fadt), 5);
+}
+
 /* DSDT */
 static void
 build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
@@ -181,6 +206,7 @@ static
 void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 {
 GArray *table_offsets;
+unsigned dsdt;
 GArray *tables_blob = tables->table_data;
 
 table_offsets = g_array_new(false, true /* clear */,
@@ -200,8 +226,13 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
  */
 
 /* DSDT is pointed to by FADT */
+dsdt = tables_blob->len;
 build_dsdt(tables_blob, tables->linker, guest_info);
 
+/* FADT MADT GTDT pointed to by RSDT */
+acpi_add_table(table_offsets, tables_blob);
+build_fadt(tables_blob, tables->linker, dsdt);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index c4468f8..f29772e 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -88,46 +88,49 @@ struct AcpiTableHeader /* ACPI common table header 
*/
 typedef struct AcpiTableHeader AcpiTableHeader;
 
 /*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
+ * ACPI Fixed ACPI Description Table (FADT)
  */
+#define ACPI_FADT_COMMON_DEF /* FADT common definition */ \
+ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
+uint32_t firmware_ctrl; /* Physical address of FACS */ \
+uint32_t dsdt;  /* Physical address of DSDT */ \
+uint8_t  model; /* System Interrupt Model */ \
+uint8_t  reserved1; /* Reserved */ \
+uint16_t sci_int;   /* System vector of SCI interrupt */ \
+uint32_t smi_cmd;   /* Port address of SMI command port */ \
+uint8_t  acpi_enable;   /* Value to write to smi_cmd to enable ACPI */ \
+uint8_t  acpi_disable;  /* Value to write to smi_cmd to disable ACPI */ \
+uint8_t  S4bios_req;/* Value to write to SMI CMD to enter S4BIOS state 
*/ \
+uint8_t  reserved2; /* Reserved - must be zero */ \
+uint32_t pm1a_evt_blk;  /* Port address of Power Mgt 1a acpi_event Reg Blk 
*/ \
+uint32_t pm1b_evt_blk;  /* Port address of Power Mgt 1b acpi_event Reg Blk 
*/ \
+uint32_t pm1a_cnt_blk;  /* Port address of Power Mgt 1a Control Reg Blk */ 
\
+uint32_t pm1b_cnt_blk;  /* Port address of Power Mgt 1b Control Reg Blk */ 
\
+uint32_t pm2_cnt_blk;   /* Port address of Power Mgt 2 Control Reg Blk */ \
+uint32_t pm_tmr_blk;/* Port address of Power Mgt Timer Ctrl Reg Blk */ 
\
+uint32_t gpe0_blk;  /* Port addr of General Purpose acpi_event 0 Reg 
Blk */ \
+uint32_t gpe1_blk;  /* Port addr of General Purpose acpi_event 1 Reg 
Blk */ \
+uint8_t  pm1_evt_len;   /* Byte length of ports at pm1_x_evt_blk */ \
+uint8_t  pm1_cnt_len;   /* Byte length of ports at pm1_x_cnt_blk */ \
+uint8_t  pm2_cnt_len;   /* Byte Length of ports at pm2_cnt_blk */ \
+uint8_t  pm_tmr_len;/* Byte Length of ports at pm_tm_blk */ \
+uint8_t  gpe0_blk_len;  /* Byte Length of ports at gpe0_blk */ \
+uint8_t  gpe1_blk_len;  /* Byte Length of ports at gpe1_blk */ \
+uint8_t  gpe1_base; /* Offset in gpe model w

[Qemu-devel] [PATCH v6 18/22] hw/acpi/aml-build: Add aml_create_dword_field() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
Reviewed-by: Alex Bennée 
---
 hw/acpi/aml-build.c | 11 +++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index f5d74a4..2e13510 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -737,6 +737,17 @@ Aml *aml_field(const char *name, AmlFieldFlags flags)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
+Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x8A); /* CreateDWordFieldOp */
+aml_append(var, srcbuf);
+aml_append(var, index);
+build_append_namestring(var->buf, "%s", name);
+return var;
+}
+
 /* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
 Aml *aml_string(const char *name_format, ...)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 4fc0e5b..9fc4057 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -261,6 +261,7 @@ Aml *aml_package(uint8_t num_elements);
 Aml *aml_buffer(int buffer_size, uint8_t *byte_list);
 Aml *aml_resource_template(void);
 Aml *aml_field(const char *name, AmlFieldFlags flags);
+Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name);
 Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
 
-- 
2.0.4





[Qemu-devel] [PATCH v6 19/22] hw/acpi/aml-build: Add aml_dword_io() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
Reviewed-by: Alex Bennée 
---
 hw/acpi/aml-build.c | 18 ++
 include/hw/acpi/aml-build.h |  5 +
 2 files changed, 23 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 2e13510..67b7719 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -958,6 +958,24 @@ Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed 
max_fixed,
 }
 
 /*
+ * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
+ *
+ * More verbose description at:
+ * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
+ */
+Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
+ AmlDecode dec, AmlISARanges isa_ranges,
+ uint32_t addr_gran, uint32_t addr_min,
+ uint32_t addr_max, uint32_t addr_trans,
+ uint32_t len)
+
+{
+return aml_dword_as_desc(aml_io_range, min_fixed, max_fixed, dec,
+addr_gran, addr_min, addr_max, addr_trans, len,
+isa_ranges);
+}
+
+/*
  * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
  *
  * More verbose description at:
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 9fc4057..5ff9c14 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -238,6 +238,11 @@ Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed 
max_fixed,
  uint16_t addr_gran, uint16_t addr_min,
  uint16_t addr_max, uint16_t addr_trans,
  uint16_t len);
+Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
+ AmlDecode dec, AmlISARanges isa_ranges,
+ uint32_t addr_gran, uint32_t addr_min,
+ uint32_t addr_max, uint32_t addr_trans,
+ uint32_t len);
 Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
   AmlMaxFixed max_fixed, AmlCacheble cacheable,
   AmlReadAndWrite read_and_write,
-- 
2.0.4





[Qemu-devel] [PATCH v6 01/22] hw/i386: Move ACPI header definitions in an arch-independent location

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

The ACPI related header file acpi-defs.h, includes definitions that
apply on other architectures as well. Move it in `include/hw/acpi/`
to sanely include it from other architectures.

Signed-off-by: Alvise Rigo 
Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/i386/acpi-build.c|   2 +-
 hw/i386/acpi-defs.h | 368 
 include/hw/acpi/acpi-defs.h | 368 
 tests/bios-tables-test.c|   2 +-
 4 files changed, 370 insertions(+), 370 deletions(-)
 delete mode 100644 hw/i386/acpi-defs.h
 create mode 100644 include/hw/acpi/acpi-defs.h

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a361357..5515837 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -32,7 +32,7 @@
 #include "hw/i386/pc.h"
 #include "target-i386/cpu.h"
 #include "hw/timer/hpet.h"
-#include "hw/i386/acpi-defs.h"
+#include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
deleted file mode 100644
index c4468f8..000
--- a/hw/i386/acpi-defs.h
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see .
- */
-#ifndef QEMU_ACPI_DEFS_H
-#define QEMU_ACPI_DEFS_H
-
-enum {
-ACPI_FADT_F_WBINVD,
-ACPI_FADT_F_WBINVD_FLUSH,
-ACPI_FADT_F_PROC_C1,
-ACPI_FADT_F_P_LVL2_UP,
-ACPI_FADT_F_PWR_BUTTON,
-ACPI_FADT_F_SLP_BUTTON,
-ACPI_FADT_F_FIX_RTC,
-ACPI_FADT_F_RTC_S4,
-ACPI_FADT_F_TMR_VAL_EXT,
-ACPI_FADT_F_DCK_CAP,
-ACPI_FADT_F_RESET_REG_SUP,
-ACPI_FADT_F_SEALED_CASE,
-ACPI_FADT_F_HEADLESS,
-ACPI_FADT_F_CPU_SW_SLP,
-ACPI_FADT_F_PCI_EXP_WAK,
-ACPI_FADT_F_USE_PLATFORM_CLOCK,
-ACPI_FADT_F_S4_RTC_STS_VALID,
-ACPI_FADT_F_REMOTE_POWER_ON_CAPABLE,
-ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL,
-ACPI_FADT_F_FORCE_APIC_PHYSICAL_DESTINATION_MODE,
-ACPI_FADT_F_HW_REDUCED_ACPI,
-ACPI_FADT_F_LOW_POWER_S0_IDLE_CAPABLE,
-};
-
-/*
- * ACPI 2.0 Generic Address Space definition.
- */
-struct Acpi20GenericAddress {
-uint8_t  address_space_id;
-uint8_t  register_bit_width;
-uint8_t  register_bit_offset;
-uint8_t  reserved;
-uint64_t address;
-} QEMU_PACKED;
-typedef struct Acpi20GenericAddress Acpi20GenericAddress;
-
-struct AcpiRsdpDescriptor {/* Root System Descriptor Pointer */
-uint64_t signature;  /* ACPI signature, contains "RSD PTR " */
-uint8_t  checksum;   /* To make sum of struct == 0 */
-uint8_t  oem_id [6]; /* OEM identification */
-uint8_t  revision;   /* Must be 0 for 1.0, 2 for 2.0 */
-uint32_t rsdt_physical_address;  /* 32-bit physical address of RSDT */
-uint32_t length; /* XSDT Length in bytes including hdr */
-uint64_t xsdt_physical_address;  /* 64-bit physical address of XSDT */
-uint8_t  extended_checksum;  /* Checksum of entire table */
-uint8_t  reserved [3];   /* Reserved field must be 0 */
-} QEMU_PACKED;
-typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor;
-
-/* Table structure from Linux kernel (the ACPI tables are under the
-   BSD license) */
-
-
-#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
-uint32_t signature;  /* ACPI signature (4 ASCII characters) */ \
-uint32_t length; /* Length of table, in bytes, including 
header */ \
-uint8_t  revision;   /* ACPI Specification minor version # */ \
-uint8_t  checksum;   /* To make sum of entire table == 0 */ \
-uint8_t  oem_id [6]; /* OEM identification */ \
-uint8_t  oem_table_id [8];   /* OEM table identification */ \
-uint32_t oem_revision;   /* OEM revision number */ \
-uint8_t  asl_compiler_id [4];/* ASL compiler vendor ID */ \
-uint32_t asl_compiler_revision;  /* ASL compiler revision number */
-
-
-struct AcpiTableHeader /* ACPI common table header */
-{
-ACPI_TABLE_HEADER_DEF
-} QEMU_PACKED;
-typedef struct AcpiTableHeader AcpiTableHeader;
-
-/*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
- */
-struct AcpiFadtDescriptorRev1
-{
-ACPI_TABLE_HEADER_DEF /* ACPI common table header */
-uint32_t firmware_ctrl;  /* Physical add

[Qemu-devel] [PATCH v6 05/22] hw/acpi/aml-build: Add aml_interrupt() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Add aml_interrupt() for describing device interrupt in resource template.
These can be used to generating DSDT table for ACPI on ARM.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 28 +
 include/hw/acpi/aml-build.h | 50 +
 2 files changed, 78 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 61407b7..babe4d6 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -532,6 +532,34 @@ Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
 return var;
 }
 
+/*
+ * ACPI 1.0: 6.4.3.6 Interrupt (Interrupt Resource Descriptor Macro)
+ */
+Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
+   AmlLevelAndEdge level_and_edge,
+   AmlActiveHighAndLow high_and_low,
+   AmlExclusiveAndShared exclusive_and_shared,
+   AmlWakeCap wake_capable, uint32_t irq)
+{
+Aml *var = aml_alloc();
+uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
+| (high_and_low << 2) | (exclusive_and_shared << 3)
+| (wake_capable << 4);
+
+build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
+build_append_byte(var->buf, 6); /* Length, bits[7:0] minimum value = 6 */
+build_append_byte(var->buf, 0); /* Length, bits[15:8] minimum value = 0 */
+build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
+build_append_byte(var->buf, 0x01); /* Interrupt table length = 1 */
+
+/* Interrupt Number */
+build_append_byte(var->buf, extract32(irq, 0, 8)); /* bits[7:0] */
+build_append_byte(var->buf, extract32(irq, 8, 8)); /* bits[15:8] */
+build_append_byte(var->buf, extract32(irq, 16, 8)); /* bits[23:16] */
+build_append_byte(var->buf, extract32(irq, 24, 8)); /* bits[31:24] */
+return var;
+}
+
 /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
 uint8_t aln, uint8_t len)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 154823b..5b60744 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -105,6 +105,51 @@ typedef enum {
 aml_ReadWrite = 1,
 } AmlReadAndWrite;
 
+/*
+ * ACPI 1.0b: Table 6-28 Extended Interrupt Descriptor Definition
+ * Interrupt Vector Flags Bits[0] Consumer/Producer
+ */
+typedef enum {
+aml_consumer_producer = 0,
+aml_consumer = 1,
+} AmlConsumerAndProducer;
+
+/*
+ * ACPI 1.0b: Table 6-28 Extended Interrupt Descriptor Definition
+ * _HE field definition
+ */
+typedef enum {
+aml_level = 0,
+aml_edge = 1,
+} AmlLevelAndEdge;
+
+/*
+ * ACPI 1.0b: Table 6-28 Extended Interrupt Descriptor Definition
+ * _LL field definition
+ */
+typedef enum {
+aml_active_high = 0,
+aml_active_low = 1,
+} AmlActiveHighAndLow;
+
+/*
+ * ACPI 1.0b: Table 6-28 Extended Interrupt Descriptor Definition
+ * _SHR field definition
+ */
+typedef enum {
+aml_exclusive = 0,
+aml_shared = 1,
+} AmlExclusiveAndShared;
+
+/*
+ * ACPI 5.1: Table 6-203 Extended Interrupt Descriptor Definition
+ * _WKC field definition
+ */
+typedef enum {
+aml_not_wake_capable = 0,
+aml_wake_capable = 1,
+} AmlWakeCap;
+
 typedef
 struct AcpiBuildTables {
 GArray *table_data;
@@ -164,6 +209,11 @@ Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, 
Aml *arg3);
 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4);
 Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
 AmlReadAndWrite read_and_write);
+Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
+   AmlLevelAndEdge level_and_edge,
+   AmlActiveHighAndLow high_and_low,
+   AmlExclusiveAndShared exclusive_and_shared,
+   AmlWakeCap wake_capable, uint32_t irq);
 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
 uint8_t aln, uint8_t len);
 Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
-- 
2.0.4





[Qemu-devel] [PATCH v6 17/22] hw/acpi/aml-build: Add aml_else() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
Reviewed-by: Alex Bennée 
---
 hw/acpi/aml-build.c | 7 +++
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index b03740d..f5d74a4 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -632,6 +632,13 @@ Aml *aml_if(Aml *predicate)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
+Aml *aml_else(void)
+{
+Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
+return var;
+}
+
 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
 Aml *aml_method(const char *name, int arg_count)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 6c3d17a..4fc0e5b 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -256,6 +256,7 @@ Aml *aml_scope(const char *name_format, ...) 
GCC_FMT_ATTR(1, 2);
 Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_method(const char *name, int arg_count);
 Aml *aml_if(Aml *predicate);
+Aml *aml_else(void);
 Aml *aml_package(uint8_t num_elements);
 Aml *aml_buffer(int buffer_size, uint8_t *byte_list);
 Aml *aml_resource_template(void);
-- 
2.0.4





[Qemu-devel] [PATCH v6 13/22] hw/acpi/aml-build: Make aml_buffer() definition consistent with the spec

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

According to ACPI spec, DefBuffer can take two parameters: BufferSize
and ByteList. Make it consistent with the spec. If we want to request
uninitialized buffer, pass ByteList as NULL to aml_buffer() to
reserve spaces.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 15 ++-
 include/hw/acpi/aml-build.h |  2 +-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index b99bb13..a38a536 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -643,9 +643,22 @@ Aml *aml_resource_template(void)
 }
 
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
-Aml *aml_buffer(void)
+Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
 {
+int i;
 Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
+
+for (i = 0; i < buffer_size; i++) {
+/* (byte_list == NULL) means requesting uninitialized buffer, only
+ * need to reserve spaces.
+ */
+if (byte_list == NULL) {
+build_append_byte(var->buf, 0x0);
+} else {
+build_append_byte(var->buf, *(byte_list + i));
+}
+}
+
 return var;
 }
 
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index d1b9fe7..69d7813 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -255,7 +255,7 @@ Aml *aml_device(const char *name_format, ...) 
GCC_FMT_ATTR(1, 2);
 Aml *aml_method(const char *name, int arg_count);
 Aml *aml_if(Aml *predicate);
 Aml *aml_package(uint8_t num_elements);
-Aml *aml_buffer(void);
+Aml *aml_buffer(int buffer_size, uint8_t *byte_list);
 Aml *aml_resource_template(void);
 Aml *aml_field(const char *name, AmlFieldFlags flags);
 Aml *aml_varpackage(uint32_t num_elements);
-- 
2.0.4





[Qemu-devel] [PATCH v6 14/22] hw/acpi/aml-build: Add ToUUID macro

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Add ToUUID macro, this is useful for generating PCIe ACPI table.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 46 +
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 47 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index a38a536..d9c9876 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -961,6 +961,52 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
  addr_trans, len, flags);
 }
 
+static uint8_t Hex2Byte(const char *src)
+{
+int hi = Hex2Digit(*src++);
+int lo = Hex2Digit(*src);
+
+g_assert(((hi >= 0) && (hi <= 15)) && ((lo >= 0) && (lo <= 15)));
+return (hi << 4) | lo;
+}
+
+/*
+ * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
+ * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+ * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
+ */
+Aml *aml_touuid(const char *uuid)
+{
+Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
+
+/* format: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp */
+g_assert((strlen(uuid) == 36) && (uuid[8] == '-') && (uuid[13] == '-')
+  && (uuid[18] == '-') && (uuid[23] == '-'));
+
+build_append_byte(var->buf, Hex2Byte(uuid + 6)); /* dd - at offset 00 */
+build_append_byte(var->buf, Hex2Byte(uuid + 4)); /* cc - at offset 01 */
+build_append_byte(var->buf, Hex2Byte(uuid + 2)); /* bb - at offset 02 */
+build_append_byte(var->buf, Hex2Byte(uuid + 0)); /* aa - at offset 03 */
+
+build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
+build_append_byte(var->buf, Hex2Byte(uuid + 9)); /* ee - at offset 05 */
+
+build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
+build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
+
+build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
+build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
+
+build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
+build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
+build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
+build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
+build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
+build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
+
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 69d7813..7399f04 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -259,6 +259,7 @@ Aml *aml_buffer(int buffer_size, uint8_t *byte_list);
 Aml *aml_resource_template(void);
 Aml *aml_field(const char *name, AmlFieldFlags flags);
 Aml *aml_varpackage(uint32_t num_elements);
+Aml *aml_touuid(const char *uuid);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
2.0.4





[Qemu-devel] [PATCH v6 06/22] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

DSDT consists of the usual common table header plus a definition
block in AML encoding which describes all devices in the platform.

After initializing DSDT with header information the namespace is
created which is followed by the device encodings. The devices are
described using the Resource Template for the 32-Bit Fixed Memory
Range and the Extended Interrupt Descriptors.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c | 128 +++
 1 file changed, 128 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 960206d..1a00ad7 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -42,6 +42,130 @@
 #include "hw/hw.h"
 #include "hw/acpi/aml-build.h"
 
+static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
+{
+uint16_t i;
+
+for (i = 0; i < smp_cpus; i++) {
+Aml *dev = aml_device("C%03x", i);
+aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
+aml_append(dev, aml_name_decl("_UID", aml_int(i)));
+Aml *crs = aml_resource_template();
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+}
+
+static void acpi_dsdt_add_uart(Aml *scope, const MemMap *uart_memmap,
+   const int *uart_irq)
+{
+Aml *dev = aml_device("COM0");
+aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0011")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(uart_memmap->addr,
+   uart_memmap->size, aml_ReadWrite));
+aml_append(crs,
+   aml_interrupt(aml_consumer, aml_level, aml_active_high,
+   aml_exclusive, aml_not_wake_capable, *uart_irq + 32));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
+static void acpi_dsdt_add_rtc(Aml *scope, const MemMap *rtc_memmap,
+  const int *rtc_irq)
+{
+Aml *dev = aml_device("RTC0");
+aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0013")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(rtc_memmap->addr,
+   rtc_memmap->size, aml_ReadWrite));
+aml_append(crs,
+   aml_interrupt(aml_consumer, aml_level, aml_active_high,
+   aml_exclusive, aml_not_wake_capable, *rtc_irq + 32));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
+static void acpi_dsdt_add_flash(Aml *scope, const MemMap *flash_memmap)
+{
+Aml *dev, *crs;
+hwaddr base = flash_memmap->addr;
+hwaddr size = flash_memmap->size;
+
+dev = aml_device("FLS0");
+aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(base, size, aml_ReadWrite));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+
+dev = aml_device("FLS1");
+aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
+aml_append(dev, aml_name_decl("_UID", aml_int(1)));
+crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(base + size, size, aml_ReadWrite));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
+static void acpi_dsdt_add_virtio(Aml *scope, const MemMap *virtio_mmio_memmap,
+ const int *mmio_irq, int num)
+{
+hwaddr base = virtio_mmio_memmap->addr;
+hwaddr size = virtio_mmio_memmap->size;
+int irq = *mmio_irq + 32;
+int i;
+
+for (i = 0; i < num; i++) {
+Aml *dev = aml_device("VR%02u", i);
+aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005")));
+aml_append(dev, aml_name_decl("_UID", aml_int(i)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(base, size, aml_ReadWrite));
+aml_append(crs,
+   aml_interrupt(aml_consumer, aml_level, aml_active_high,
+   aml_exclusive, aml_not_wake_capable, irq + i));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+base += size;
+}
+}
+
+/* DSDT */
+static void
+build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+{
+Aml *scope, *dsdt;
+AcpiDsdtInfo *info = guest_info->dsdt_info;
+
+dsdt = init_aml_allocator();
+/* Reserve space for header */
+acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader));
+
+scope = aml_scope("\\_SB");
+acpi_dsdt_add_cpus(scope, guest_info->smp_cpus);
+acpi_dsdt_add_uart(scope, info->uart_memmap, info->uart_irq);
+acpi_dsdt_add_rtc(scope, info->rtc_memmap, inf

[Qemu-devel] [PATCH v6 22/22] hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Expose the needed device information to the table generation
insfrastructure and register a machine_init_done notify to
call virt_acpi_build().

Add CONFIG_ACPI to arm-softmmu.mak.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 default-configs/arm-softmmu.mak  |  1 +
 default-configs/i386-softmmu.mak |  3 ++
 default-configs/mips-softmmu.mak |  3 ++
 default-configs/mips64-softmmu.mak   |  3 ++
 default-configs/mips64el-softmmu.mak |  3 ++
 default-configs/mipsel-softmmu.mak   |  3 ++
 default-configs/x86_64-softmmu.mak   |  3 ++
 hw/acpi/Makefile.objs|  5 ++-
 hw/arm/virt.c| 78 
 hw/i2c/Makefile.objs |  2 +-
 10 files changed, 94 insertions(+), 10 deletions(-)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a767e4b..74f1db3 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -101,3 +101,4 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
+CONFIG_ACPI=y
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 6a74e00..d2de500 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_IDE_ISA=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index cce2c81..c96d42d 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/mips64-softmmu.mak 
b/default-configs/mips64-softmmu.mak
index 7a88a08..d229f9e 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 095de43..ea31b8b 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/mipsel-softmmu.mak 
b/default-configs/mipsel-softmmu.mak
index 0e25108..9a4462e 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index 46b87dd..11019b6 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_IDE_ISA=y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index b9fefa7..511771a 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -1,5 +1,6 @@
-common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
-common-obj-$(CONFIG_ACPI) += memory_hotplug.o
+common-obj-$(CONFIG_ACPI_CORE) += core.o piix4.o ich9.o pcihp.o
+common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
+common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
 common-obj-$(CONFIG_ACPI) += aml-build.o
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 565f573..9291045 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -43,6 +43,7 @@
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
 #include "hw/pci-host/gpex.h"
+#include "hw/arm/virt-acpi-build.h"
 
 #define NUM_VIRTIO_TRANSPORTS 32
 
@@ -60,6 +61,11 @@
 #define GIC_FDT_IRQ_PPI_CPU_START 8
 #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
 
+#define ARCH_TIMER_VIRT_IRQ   11
+#define ARCH_TIMER_S_EL1_IRQ  13
+#define ARCH_TIMER_NS_EL1_IRQ 14
+#define ARCH_TIMER_NS_EL2_IRQ 10
+
 enum {
 VIRT_FLASH,
 VIRT_MEM,
@@ -149,6 +155,29 @@ static const int a15irqmap[] = {
 [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
 };
 
+static AcpiMadtInfo madt_info = {
+(MemMap *)&a15memmap[VIRT_GIC_CPU],
+(MemMap *)&a15memmap[VIRT_GIC_DIST]
+};
+
+static AcpiDsdtInfo dsdt_info = {
+(MemMap *)&a15memmap[VIRT_UART],
+   

[Qemu-devel] [PATCH v6 20/22] hw/acpi/aml-build: Add Unicode macro

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/acpi/aml-build.c | 18 ++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 67b7719..06f9d37 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1061,6 +1061,24 @@ Aml *aml_touuid(const char *uuid)
 return var;
 }
 
+/*
+ * ACPI 2.0b: 16.2.3.6.4.3  Unicode Macro (Convert Ascii String To Unicode)
+ */
+Aml *aml_unicode(const char *str)
+{
+Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
+
+while (*str != '\0') {
+build_append_byte(var->buf, 0);
+build_append_byte(var->buf, *str);
+str++;
+}
+build_append_byte(var->buf, 0);
+build_append_byte(var->buf, *str);
+
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 5ff9c14..39b44e4 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -269,6 +269,7 @@ Aml *aml_field(const char *name, AmlFieldFlags flags);
 Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name);
 Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
+Aml *aml_unicode(const char *str);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
2.0.4





[Qemu-devel] [PATCH v6 11/22] hw/arm/virt-acpi-build: Generate RSDP table

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

RSDP points to RSDT which in turn points to other tables.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
Reviewed-by: Alex Bennée 
---
 hw/arm/virt-acpi-build.c | 35 ++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 401e634..caa7096 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -152,6 +152,35 @@ static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
*virtio_mmio_memmap,
 }
 }
 
+/* RSDP */
+static GArray *
+build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
+{
+AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+
+bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
+ true /* fseg memory */);
+
+memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
+memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));
+rsdp->length = cpu_to_le32(sizeof(*rsdp));
+rsdp->revision = 0x02;
+
+/* Point to RSDT */
+rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
+/* Address to be filled by Guest linker */
+bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   rsdp_table, &rsdp->rsdt_physical_address,
+   sizeof rsdp->rsdt_physical_address);
+rsdp->checksum = 0;
+/* Checksum to be filled by Guest linker */
+bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
+rsdp, rsdp, sizeof *rsdp, &rsdp->checksum);
+
+return rsdp_table;
+}
+
 /* GTDT */
 static void
 build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
@@ -284,7 +313,7 @@ static
 void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 {
 GArray *table_offsets;
-unsigned dsdt;
+unsigned dsdt, rsdt;
 VirtAcpiCpuInfo cpuinfo;
 GArray *tables_blob = tables->table_data;
 
@@ -321,8 +350,12 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 build_gtdt(tables_blob, tables->linker, guest_info);
 
 /* RSDT is pointed to by RSDP */
+rsdt = tables_blob->len;
 build_rsdt(tables_blob, tables->linker, table_offsets);
 
+/* RSDP is in FSEG memory, so allocate it separately */
+build_rsdp(tables->rsdp, tables->linker, rsdt);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
-- 
2.0.4





[Qemu-devel] [PATCH v6 16/22] hw/acpi/aml-build: Add aml_lnot() term

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
Reviewed-by: Alex Bennée 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index bda99bf..b03740d 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -607,6 +607,14 @@ Aml *aml_irq_no_flags(uint8_t irq)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
+Aml *aml_lnot(Aml *arg)
+{
+Aml *var = aml_opcode(0x92 /* LNotOp */);
+aml_append(var, arg);
+return var;
+}
+
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
 Aml *aml_equal(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index a039ffe..6c3d17a 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -224,6 +224,7 @@ Aml *aml_named_field(const char *name, unsigned length);
 Aml *aml_reserved_field(unsigned length);
 Aml *aml_local(int num);
 Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
+Aml *aml_lnot(Aml *arg);
 Aml *aml_equal(Aml *arg1, Aml *arg2);
 Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
const char *name_format, ...) GCC_FMT_ATTR(4, 5);
-- 
2.0.4





[Qemu-devel] [PATCH v6 12/22] hw/arm/virt-acpi-build: Add PCIe info and generate MCFG table

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Add PCIe info struct, prepare for building PCIe table.
And generate MCFG table.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c | 21 +
 include/hw/arm/virt-acpi-build.h |  9 +
 2 files changed, 30 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index caa7096..ceea689 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -181,6 +181,24 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned 
rsdt)
 return rsdp_table;
 }
 
+static void
+build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+{
+AcpiTableMcfg *mcfg;
+AcpiPcieInfo *info = guest_info->pcie_info;
+int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
+
+mcfg = acpi_data_push(table_data, len);
+mcfg->allocation[0].address = cpu_to_le64(info->pcie_ecam.addr);
+
+/* Only a single allocation so no need to play with segments */
+mcfg->allocation[0].pci_segment = cpu_to_le16(0);
+mcfg->allocation[0].start_bus_number = 0;
+mcfg->allocation[0].end_bus_number = info->nr_pcie_buses - 1;
+
+build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1);
+}
+
 /* GTDT */
 static void
 build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
@@ -349,6 +367,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables_blob);
 build_gtdt(tables_blob, tables->linker, guest_info);
 
+acpi_add_table(table_offsets, tables_blob);
+build_mcfg(tables_blob, tables->linker, guest_info);
+
 /* RSDT is pointed to by RSDP */
 rsdt = tables_blob->len;
 build_rsdt(tables_blob, tables->linker, table_offsets);
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index 60d6f0f..4dbc5d3 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -53,6 +53,14 @@ typedef struct AcpiDsdtInfo {
 const MemMap *flash_memmap;
 } AcpiDsdtInfo;
 
+typedef struct AcpiPcieInfo {
+const int *pcie_irq;
+MemMap pcie_mmio;
+MemMap pcie_ioport;
+MemMap pcie_ecam;
+int nr_pcie_buses;
+} AcpiPcieInfo;
+
 typedef struct VirtGuestInfo {
 int smp_cpus;
 int max_cpus;
@@ -60,6 +68,7 @@ typedef struct VirtGuestInfo {
 AcpiMadtInfo *madt_info;
 AcpiDsdtInfo *dsdt_info;
 AcpiGtdtInfo *gtdt_info;
+AcpiPcieInfo *pcie_info;
 } VirtGuestInfo;
 
 
-- 
2.0.4





[Qemu-devel] [PATCH v6 21/22] hw/arm/virt-acpi-build: Add PCIe controller in ACPI DSDT table

2015-05-07 Thread Shannon Zhao
From: Shannon Zhao 

Add PCIe controller in ACPI DSDT table, so the guest can detect
the PCIe.

Signed-off-by: Shannon Zhao 
Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ceea689..002e004 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -41,6 +41,8 @@
 #include "hw/loader.h"
 #include "hw/hw.h"
 #include "hw/acpi/aml-build.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pci.h"
 
 typedef struct VirtAcpiCpuInfo {
 DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT);
@@ -152,6 +154,154 @@ static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
*virtio_mmio_memmap,
 }
 }
 
+static void acpi_dsdt_add_pci(Aml *scope, AcpiPcieInfo *info)
+{
+Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
+int i, bus_no;
+int irq = *info->pcie_irq + 32;
+
+Aml *dev = aml_device("%s", "PCI0");
+aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08")));
+aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03")));
+aml_append(dev, aml_name_decl("_SEG", aml_int(0)));
+aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
+aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
+aml_append(dev, aml_name_decl("_UID", aml_string("PCI0")));
+aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
+
+/* Declare the PCI Routing Table. */
+Aml *rt_pkg = aml_package(info->nr_pcie_buses * PCI_NUM_PINS);
+for (bus_no = 0; bus_no < info->nr_pcie_buses; bus_no++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
+int gsi = (i + bus_no) % PCI_NUM_PINS;
+Aml *pkg = aml_package(4);
+aml_append(pkg, aml_int((bus_no << 16) | 0x));
+aml_append(pkg, aml_int(i));
+aml_append(pkg, aml_name("GSI%d", gsi));
+aml_append(pkg, aml_int(0));
+aml_append(rt_pkg, pkg);
+}
+}
+aml_append(dev, aml_name_decl("_PRT", rt_pkg));
+
+/* Create GSI link device */
+for (i = 0; i < PCI_NUM_PINS; i++) {
+Aml *dev_gsi = aml_device("GSI%d", i);
+aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F")));
+aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0)));
+crs = aml_resource_template();
+aml_append(crs,
+   aml_interrupt(aml_consumer, aml_level, aml_active_high,
+   aml_exclusive, aml_not_wake_capable, irq + i));
+aml_append(dev_gsi, aml_name_decl("_PRS", crs));
+crs = aml_resource_template();
+aml_append(crs,
+   aml_interrupt(aml_consumer, aml_level, aml_active_high,
+   aml_exclusive, aml_not_wake_capable, irq + i));
+aml_append(dev_gsi, aml_name_decl("_CRS", crs));
+method = aml_method("_SRS", 1);
+aml_append(dev_gsi, method);
+aml_append(dev, dev_gsi);
+}
+
+method = aml_method("_CBA", 0);
+aml_append(method, aml_return(aml_int(info->pcie_ecam.addr)));
+aml_append(dev, method);
+
+method = aml_method("_CRS", 0);
+Aml *rbuf = aml_resource_template();
+aml_append(rbuf,
+aml_word_bus_number(aml_min_fixed, aml_max_fixed, aml_pos_decode,
+0x, 0x, info->nr_pcie_buses - 1,
+0x, info->nr_pcie_buses));
+aml_append(rbuf,
+aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
+ aml_non_cacheable, aml_ReadWrite,
+ 0x, info->pcie_mmio.addr,
+ info->pcie_mmio.addr + info->pcie_mmio.size - 1,
+ 0x, info->pcie_mmio.size));
+aml_append(rbuf,
+aml_dword_io(aml_min_fixed, aml_max_fixed,
+ aml_pos_decode, aml_entire_range,
+ 0x, 0x, info->pcie_ioport.size - 1,
+ info->pcie_ioport.addr, info->pcie_ioport.size));
+
+aml_append(method, aml_name_decl("RBUF", rbuf));
+aml_append(method, aml_return(rbuf));
+aml_append(dev, method);
+
+/* Declare an _OSC (OS Control Handoff) method */
+aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
+aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
+method = aml_method("_OSC", 4);
+aml_append(method,
+aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
+
+/* PCI Firmware Specification 3.0
+ * 4.5.1. _OSC Interface for PCI Host Bridge Devices
+ * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
+ * identified by the Universal Unique IDentifier (UUID)
+ * 33DB4D5B-1FF7-401C-9657-7441C03DD766
+ */
+UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
+ifctx = aml_if(aml_equal(aml_arg(0), UUID));
+aml_append(ifctx,
+aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
+aml_append(if

Re: [Qemu-devel] [RFC v0 PATCH] cpus: Convert cpu_index into a bitmap

2015-05-07 Thread Bharata B Rao
On Wed, Mar 18, 2015 at 11:50:04AM +0530, Bharata B Rao wrote:
> On Tue, Mar 17, 2015 at 11:56:04AM +0100, Andreas Färber wrote:
> > Am 17.03.2015 um 09:39 schrieb Bharata B Rao:
> > > On Tue, Mar 17, 2015 at 07:56:41AM +0100, Alexander Graf wrote:
> > >>
> > >>
> > >> On 13.03.15 12:56, Bharata B Rao wrote:
> > >>> From: Bharata B Rao 
> > >>>
> > >>> Currently CPUState.cpu_index is monotonically increasing and a newly
> > >>> created CPU always gets the next higher index. The next available
> > >>> index is calculated by counting the existing number of CPUs. This is
> > >>> fine as long as we only add CPUs, but there are architectures which
> > >>> are starting to support CPU removal too. For an architecture like 
> > >>> PowerPC
> > >>> which derives its CPU identifier (device tree ID) from cpu_index, the
> > >>> existing logic of generating cpu_index values causes problems.
> > >>>
> > >>> With the currently proposed method of handling vCPU removal by parking
> > >>> the vCPU fd in QEMU
> > >>> (Ref: 
> > >>> http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg02604.html),
> > >>> generating cpu_index this way will not work for PowerPC.
> > >>>
> > >>> This patch changes the way cpu_index is handed out by maintaining
> > >>> a bit map of the CPUs that tracks both addition and removal of CPUs.
> > >>>
> > >>> I am not sure if this is the right and an acceptable approach. The
> > >>> alternative is to do something similar for PowerPC alone and not
> > >>> depend on cpu_index.
> > >>>
> > >>> I have tested this with out-of-the-tree patches for CPU hot plug and
> > >>> removal on x86 and sPAPR PowerPC.
> > >>>
> > >>> Signed-off-by: Bharata B Rao 
> > >>> ---
> > >>>  exec.c  | 39 
> > >>> +--
> > >>>  include/exec/exec-all.h |  1 +
> > >>>  target-alpha/cpu.c  |  6 ++
> > >>>  target-arm/cpu.c|  1 +
> > >>>  target-cris/cpu.c   |  6 ++
> > >>>  target-i386/cpu.c   |  6 ++
> > >>>  target-lm32/cpu.c   |  6 ++
> > >>>  target-m68k/cpu.c   |  6 ++
> > >>>  target-microblaze/cpu.c |  6 ++
> > >>>  target-mips/cpu.c   |  6 ++
> > >>>  target-moxie/cpu.c  |  6 ++
> > >>>  target-openrisc/cpu.c   |  6 ++
> > >>>  target-ppc/translate_init.c |  6 ++
> > >>>  target-s390x/cpu.c  |  1 +
> > >>>  target-sh4/cpu.c|  6 ++
> > >>>  target-sparc/cpu.c  |  1 +
> > >>>  target-tricore/cpu.c|  5 +
> > >>>  target-unicore32/cpu.c  |  6 ++
> > >>>  target-xtensa/cpu.c |  6 ++
> > >>>  19 files changed, 116 insertions(+), 10 deletions(-)
> > >>>
> > >>> diff --git a/exec.c b/exec.c
> > >>> index e97071a..7760f2d 100644
> > >>> --- a/exec.c
> > >>> +++ b/exec.c
> > >>> @@ -530,21 +530,40 @@ void tcg_cpu_address_space_init(CPUState *cpu, 
> > >>> AddressSpace *as)
> > >>>  }
> > >>>  #endif
> > >>>  
> > >>> +static DECLARE_BITMAP(cpu_index_map, MAX_CPUMASK_BITS);
> > >>> +
> > >>> +#ifdef CONFIG_USER_ONLY
> > >>> +int max_cpus = 1; /* TODO: Check if this is correct ? */
> > >>> +#endif
> > >>> +
> > >>> +static int cpu_get_free_index(void)
> > >>> +{
> > >>> +int cpu = find_first_zero_bit(cpu_index_map, max_cpus);
> > >>> +
> > >>> +if (cpu == max_cpus) {
> > >>> +fprintf(stderr, "WARNING: qemu: Trying to use more "
> > >>> +"CPUs than allowed max of %d\n", max_cpus);
> > >>> +return max_cpus;
> > >>> +} else {
> > >>> +bitmap_set(cpu_index_map, cpu, 1);
> > >>> +return cpu;
> > >>> +}
> > >>> +}
> > >>> +
> > >>> +void cpu_exec_exit(CPUState *cpu)
> > >>> +{
> > >>> +bitmap_clear(cpu_index_map, cpu->cpu_index, 1);
> > >>> +}
> > >>> +
> > >>>  void cpu_exec_init(CPUArchState *env)
> > >>>  {
> > >>>  CPUState *cpu = ENV_GET_CPU(env);
> > >>>  CPUClass *cc = CPU_GET_CLASS(cpu);
> > >>> -CPUState *some_cpu;
> > >>> -int cpu_index;
> > >>>  
> > >>>  #if defined(CONFIG_USER_ONLY)
> > >>>  cpu_list_lock();
> > >>>  #endif
> > >>> -cpu_index = 0;
> > >>> -CPU_FOREACH(some_cpu) {
> > >>> -cpu_index++;
> > >>> -}
> > >>> -cpu->cpu_index = cpu_index;
> > >>> +cpu->cpu_index = cpu_get_free_index();
> > >>>  cpu->numa_node = 0;
> > >>>  QTAILQ_INIT(&cpu->breakpoints);
> > >>>  QTAILQ_INIT(&cpu->watchpoints);
> > >>> @@ -558,16 +577,16 @@ void cpu_exec_init(CPUArchState *env)
> > >>>  cpu_list_unlock();
> > >>>  #endif
> > >>>  if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
> > >>> -vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
> > >>> +vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, 
> > >>> cpu);
> > >>>  }
> > >>>  #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
> > >>> -register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
> > >>> +register_savevm(NULL, "cpu", cpu->cpu_index, CPU_SAVE_VE

Re: [Qemu-devel] [PATCH 4/4] semihosting: add --semihosting-config arg sub-argument

2015-05-07 Thread Leon Alrae
On 07/05/2015 07:51, Liviu Ionescu wrote:
> 
>> On 06 May 2015, at 17:57, Leon Alrae  wrote:
>>
>> +static int add_semihosting_arg(const char *name, const char *val, void 
>> *opaque)
>> +{
>> +SemihostingConfig *s = opaque;
>> +if (strcmp(name, "arg") == 0) {
>> +s->argc++;
>> +s->argv = g_realloc(s->argv, s->argc * sizeof(void *));
>> +s->argv[s->argc - 1] = val;
>> +}
>> +return 0;
>> +}
> 
> being done at init time probably it has no impact, but, as a matter of style, 
> I would avoid iterating realloc when the buffer size is actually known.

At this point QEMU doesn't know the buffer size, thus we need to
traverse the list of sub-arguments to determine the number of args and
also to get the value (i.e. string) of each arg.

> 
> is it that difficult to count the "arg"s and correctly alloc the array?

This probably would require going through the list twice which wouldn't
be better in my opinion.

Leon




Re: [Qemu-devel] Bug report - Windows XP guest failure

2015-05-07 Thread Michael Tokarev
07.05.2015 09:47, Michael Tokarev wrote:
> 07.05.2015 09:12, Michael Tokarev wrote:
>> 07.05.2015 04:11, G 3 wrote:
>>> Did you boot Windows XP to the desktop? I have tested Windows 95, Windows 
>>> 2000, and Windows XP. All of them fail to boot to the desktop.
>>
>> Yes, booted to desktop and did some minimal work in there,
>> installnig one update or two.
>>
>>> Command used:
>>> ./i386-softmmu/qemu-system-i386 -boot c -hda "Windows XP Hard Drive.img" 
>>
>> Aha. You run without kvm, in tcg mode.  I don't usually do that,
>> lemme try...
> 
> Ok, I can reproduce this, winXP BSODs on boot in tcg mode.
> Git bisect points to this:
> 
> commit 23820dbfc79d1c9dce090b4c555994f2bb6a69b3
> Author: Peter Crosthwaite 
> Date:   Mon Mar 16 22:35:54 2015 -0700
> 
> exec: Respect as_translate_internal length clamp
> 
> address_space_translate_internal will clamp the *plen length argument
> based on the size of the memory region being queried. The iommu walker
> logic in addresss_space_translate was ignoring this by discarding the
> post fn call value of *plen. Fix by just always using *plen as the
> length argument throughout the fn, removing the len local variable.
> 
> This fixes a bootloader bug when a single elf section spans multiple
> QEMU memory regions.
> 
> Signed-off-by: Peter Crosthwaite 
> Message-Id: 
> <1426570554-15940-1-git-send-email-peter.crosthwa...@xilinx.com>
> Signed-off-by: Paolo Bonzini 

This winXP BSOD happens on x86_64 target too.  Reverting the
above commit from git master fixes the BSOD.

Thanks,

/mjt




Re: [Qemu-devel] [PATCH v3] block/vdi: Use bdrv_flush after metadata updates

2015-05-07 Thread Stefan Hajnoczi
On Thu, May 07, 2015 at 12:04:56PM +0800, Zhe Qiu wrote:
> From: phoeagon 
> 
> In reference to 
> b0ad5a455d7e5352d4c86ba945112011dbeadfb8~078a458e077d6b0db262c4b05fee51d01de2d1d2,
>  metadata writes to qcow2/cow/qcow/vpc/vmdk are all synced prior to 
> succeeding writes.
> 
> Only when write is successful that bdrv_flush is called.
> 
> Signed-off-by: Zhe Qiu 
> ---
>  block/vdi.c | 3 +++
>  1 file changed, 3 insertions(+)

CCing Stefan Weil and Kevin Wolf (see output from
scripts/get_maintainer.pl -f block/vdi.c).

> 
> diff --git a/block/vdi.c b/block/vdi.c
> index 7642ef3..dfe8ade 100644
> --- a/block/vdi.c
> +++ b/block/vdi.c
> @@ -713,6 +713,9 @@ static int vdi_co_write(BlockDriverState *bs,
>  logout("will write %u block map sectors starting from entry %u\n",
> n_sectors, bmap_first);
>  ret = bdrv_write(bs->file, offset, base, n_sectors);
> +if (ret >= 0) {
> +ret = bdrv_flush(bs->file);
> +}
>  }
>  
>  return ret;
> -- 
> 2.4.0
> 
> 


pgp6AD1I1FypA.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 1/7] qcow2: use one single memory block for the L2/refcount cache tables

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:25PM +0300, Alberto Garcia wrote:
> The qcow2 L2/refcount cache contains one separate table for each cache
> entry. Doing one allocation per table adds unnecessary overhead and it
> also requires us to store the address of each table separately.
> 
> Since the size of the cache is constant during its lifetime, it's
> better to have an array that contains all the tables using one single
> allocation.
> 
> In my tests measuring freshly created caches with sizes 128MB (L2) and
> 32MB (refcount) this uses around 10MB of RAM less.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c| 55 
> --
>  block/qcow2-cluster.c  | 12 +--
>  block/qcow2-refcount.c |  8 +---
>  block/qcow2.h  |  3 ++-
>  4 files changed, 39 insertions(+), 39 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpibI4_5atlS.pgp
Description: PGP signature


Re: [Qemu-devel] [Qemu-block] [PATCH 2/7] qcow2: simplify qcow2_cache_put() and qcow2_cache_entry_mark_dirty()

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:26PM +0300, Alberto Garcia wrote:
> Since all tables are now stored together, it is possible to obtain
> the position of a particular table directly from its address, so the
> operation becomes O(1).
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c | 32 +++-
>  1 file changed, 15 insertions(+), 17 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpQNSyJCbB9I.pgp
Description: PGP signature


Re: [Qemu-devel] [Qemu-block] [PATCH 3/7] qcow2: use an LRU algorithm to replace entries from the L2 cache

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:27PM +0300, Alberto Garcia wrote:
> The current algorithm to evict entries from the cache gives always
> preference to those in the lowest positions. As the size of the cache
> increases, the chances of the later elements of being removed decrease
> exponentially.
> 
> In a scenario with random I/O and lots of cache misses, entries in
> positions 8 and higher are rarely (if ever) evicted. This can be seen
> even with the default cache size, but with larger caches the problem
> becomes more obvious.
> 
> Using an LRU algorithm makes the chances of being removed from the
> cache independent from the position.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c | 31 +++
>  1 file changed, 15 insertions(+), 16 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpjB98a5MqWt.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 4/7] qcow2: remove qcow2_cache_find_entry_to_replace()

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:28PM +0300, Alberto Garcia wrote:
> A cache miss means that the whole array was traversed and the entry
> we were looking for was not found, so there's no need to traverse it
> again in order to select an entry to replace.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c | 45 -
>  1 file changed, 16 insertions(+), 29 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpKWdlL2GUQA.pgp
Description: PGP signature


Re: [Qemu-devel] [Qemu-block] [PATCH 5/7] qcow2: use a hash to look for entries in the L2 cache

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:29PM +0300, Alberto Garcia wrote:
> The current cache algorithm traverses the array starting always from
> the beginning, so the average number of comparisons needed to perform
> a lookup is proportional to the size of the array.
> 
> By using a hash of the offset as the starting point, lookups are
> faster and independent from the array size.
> 
> The hash is computed using the cluster number of the table, multiplied
> by 4 to make it perform better when there are collisions.
> 
> In my tests, using a cache with 2048 entries, this reduces the average
> number of comparisons per lookup from 430 to 2.5.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpwDYzprsil5.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 6/7] qcow2: make qcow2_cache_put() a void function

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:30PM +0300, Alberto Garcia wrote:
> This function never receives an invalid table pointer, so we can make
> it void and remove all the error checking code.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c|  7 +--
>  block/qcow2-cluster.c  | 50 
> ++
>  block/qcow2-refcount.c | 29 +
>  block/qcow2.h  |  2 +-
>  4 files changed, 17 insertions(+), 71 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpXZ7CzQFfSP.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 7/7] qcow2: style fixes in qcow2-cache.c

2015-05-07 Thread Stefan Hajnoczi
On Wed, May 06, 2015 at 04:39:31PM +0300, Alberto Garcia wrote:
> Fix pointer declaration to make it consistent with the rest of the
> code.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cache.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgpOnEBmIbnOQ.pgp
Description: PGP signature


[Qemu-devel] [PATCH v3 0/3] Introduce eventfd support for virtio-mmio

2015-05-07 Thread Pavel Fedin
 Hello!

 This is updated version of my eventfd for virtio-mmio patch. Style notes
have been considered, hopefully it's OK now.
 It's now 3 parts instead of 4, because the last one was actually a small
fix, i decided to merge it with no 3.

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia





[Qemu-devel] [PATCH v2 1/3] virtio-mmio: introduce set_host_notifier()

2015-05-07 Thread Pavel Fedin
set_host_notifier() is introduced into virtio-mmio now. Most of codes came
from virtio-pci.

Signed-off-by: Ying-Shiuan Pan 
Signed-off-by: Pavel Fedin 
---
 hw/virtio/virtio-mmio.c | 72
+
 1 file changed, 72 insertions(+)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 10123f3..6b40d56 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -23,6 +23,7 @@
 #include "hw/virtio/virtio.h"
 #include "qemu/host-utils.h"
 #include "hw/virtio/virtio-bus.h"
+#include "qemu/error-report.h"
 
 /* #define DEBUG_VIRTIO_MMIO */
 
@@ -87,8 +88,59 @@ typedef struct {
 uint32_t guest_page_shift;
 /* virtio-bus */
 VirtioBusState bus;
+bool ioeventfd_disabled;
+bool ioeventfd_started;
 } VirtIOMMIOProxy;
 
+static int virtio_mmio_set_host_notifier_internal(VirtIOMMIOProxy *proxy,
+  int n, bool assign,
+  bool set_handler)
+{
+VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+VirtQueue *vq = virtio_get_queue(vdev, n);
+EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+int r = 0;
+
+if (assign) {
+r = event_notifier_init(notifier, 1);
+if (r < 0) {
+error_report("%s: unable to init event notifier: %d",
+ __func__, r);
+return r;
+}
+virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
+memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY,
4,
+  true, n, notifier);
+} else {
+memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY,
4,
+  true, n, notifier);
+virtio_queue_set_host_notifier_fd_handler(vq, false, false);
+event_notifier_cleanup(notifier);
+}
+return r;
+}
+
+static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy)
+{
+int r;
+int n;
+VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
+if (!proxy->ioeventfd_started) {
+return;
+}
+
+for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+if (!virtio_queue_get_num(vdev, n)) {
+continue;
+}
+
+r = virtio_mmio_set_host_notifier_internal(proxy, n, false, false);
+assert(r >= 0);
+}
+proxy->ioeventfd_started = false;
+}
+
 static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned
size)
 {
 VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
@@ -342,6 +394,25 @@ static void virtio_mmio_reset(DeviceState *d)
 proxy->guest_page_shift = 0;
 }
 
+static int virtio_mmio_set_host_notifier(DeviceState *opaque, int n,
+ bool assign)
+{
+VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
+
+/* Stop using ioeventfd for virtqueue kick if the device starts using
host
+ * notifiers.  This makes it easy to avoid stepping on each others'
toes.
+ */
+proxy->ioeventfd_disabled = assign;
+if (assign) {
+virtio_mmio_stop_ioeventfd(proxy);
+}
+/* We don't need to start here: it's not needed because backend
+ * currently only stops on status change away from ok,
+ * reset, vmstop and such. If we do add code to start here,
+ * need to check vmstate, device state etc. */
+return virtio_mmio_set_host_notifier_internal(proxy, n, assign, false);
+}
+
 /* virtio-mmio device */
 
 /* This is called by virtio-bus just after the device is plugged. */
@@ -399,6 +470,7 @@ static void virtio_mmio_bus_class_init(ObjectClass
*klass, void *data)
 k->notify = virtio_mmio_update_irq;
 k->save_config = virtio_mmio_save_config;
 k->load_config = virtio_mmio_load_config;
+k->set_host_notifier = virtio_mmio_set_host_notifier;
 k->get_features = virtio_mmio_get_features;
 k->device_plugged = virtio_mmio_device_plugged;
 k->has_variable_vring_alignment = true;
-- 
1.9.5.msysgit.0


Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia




Re: [Qemu-devel] [PATCH v6 03/22] hw/arm/virt-acpi-build: Basic framework for building ACPI tables on ARM

2015-05-07 Thread Alex Bennée

Shannon Zhao  writes:

> From: Shannon Zhao 
>
> Introduce a preliminary framework in virt-acpi-build.c with the main
> ACPI build functions. It exposes the generated ACPI contents to
> guest over fw_cfg.
>
> The required ACPI v5.1 tables for ARM are:
> - RSDP: Initial table that points to XSDT
> - RSDT: Points to FADT GTDT MADT tables
> - FADT: Generic information about the machine
> - GTDT: Generic timer description table
> - MADT: Multiple APIC description table
> - DSDT: Holds all information about system devices/peripherals, pointed by 
> FADT
>
> Signed-off-by: Shannon Zhao 
> Signed-off-by: Shannon Zhao 
> ---
>  hw/arm/Makefile.objs |   1 +
>  hw/arm/virt-acpi-build.c | 184 
> +++
>  include/hw/arm/virt-acpi-build.h |  70 +++
>  qemu-options.hx  |   2 +-
>  trace-events |   3 +
>  5 files changed, 259 insertions(+), 1 deletion(-)
>  create mode 100644 hw/arm/virt-acpi-build.c
>  create mode 100644 include/hw/arm/virt-acpi-build.h
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 2577f68..a1bfb19 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o
>  obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
>  obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
>  obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
> +obj-$(CONFIG_ACPI) += virt-acpi-build.o
>  obj-y += netduino2.o
>  
>  obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> new file mode 100644
> index 000..960206d
> --- /dev/null
> +++ b/hw/arm/virt-acpi-build.c
> @@ -0,0 +1,184 @@
> +/* Support for generating ACPI tables and passing them to Guests
> + *
> + * ARM virt ACPI generation
> + *
> + * Copyright (C) 2008-2010  Kevin O'Connor 
> + * Copyright (C) 2006 Fabrice Bellard
> + * Copyright (C) 2013 Red Hat Inc
> + *
> + * Author: Michael S. Tsirkin 
> + *
> + * 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 of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> +
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> +
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + */
> +
> +#include "hw/arm/virt-acpi-build.h"
> +#include 
> +#include 
> +#include "qemu-common.h"
> +#include "qemu/bitmap.h"
> +#include "trace.h"
> +#include "qom/cpu.h"
> +#include "target-arm/cpu.h"
> +#include "hw/acpi/acpi-defs.h"
> +#include "hw/acpi/acpi.h"
> +#include "hw/nvram/fw_cfg.h"
> +#include "hw/acpi/bios-linker-loader.h"
> +#include "hw/loader.h"
> +#include "hw/hw.h"
> +#include "hw/acpi/aml-build.h"
> +
> +typedef
> +struct AcpiBuildState {
> +/* Copy of table in RAM (for patching). */
> +MemoryRegion *table_mr;
> +MemoryRegion *rsdp_mr;
> +MemoryRegion *linker_mr;
> +/* Is table patched? */
> +uint8_t patched;

I missed this last time but a uint8_t seems excessive if a bool will do
(using true/false and VMSTATE_BOOL later on).

Otherwise:

Reviewed-by: Alex Bennée 


> +VirtGuestInfo *guest_info;
> +} AcpiBuildState;
> +
> +static
> +void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
> +{
> +GArray *table_offsets;
> +
> +table_offsets = g_array_new(false, true /* clear */,
> +sizeof(uint32_t));
> +
> +bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
> + 64, false /* high memory */);
> +
> +/*
> + * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
> + * RSDP
> + * RSDT
> + * FADT
> + * GTDT
> + * MADT
> + * DSDT
> + */
> +
> +/* Cleanup memory that's no longer used. */
> +g_array_free(table_offsets, true);
> +}
> +
> +static void acpi_ram_update(MemoryRegion *mr, GArray *data)
> +{
> +uint32_t size = acpi_data_len(data);
> +
> +/* Make sure RAM size is correct - in case it got changed
> + * e.g. by migration */
> +memory_region_ram_resize(mr, size, &error_abort);
> +
> +memcpy(memory_region_get_ram_ptr(mr), data->data, size);
> +memory_region_set_dirty(mr, 0, size);
> +}
> +
> +static void virt_acpi_build_update(void *build_opaque, uint32_t offset)
> +{
> +AcpiBuildState *build_state = build_opaque;
> +AcpiBuildTables tables;
> +
> +/* No state to update or already

[Qemu-devel] [PATCH v2 2/3] virtio-mmio: introduce set_guest_notifiers

2015-05-07 Thread Pavel Fedin
Same as host notifier of virtio-mmio, most of codes came from virtio-pci.
The kvm-arm does not yet support irqfd, need to fix the hard-coded part
after
kvm-arm gets irqfd support.

Signed-off-by: Ying-Shiuan Pan 
Signed-off-by: Pavel Fedin 
---
 hw/virtio/virtio-mmio.c | 61
+
 1 file changed, 61 insertions(+)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 6b40d56..8756240 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -394,6 +394,66 @@ static void virtio_mmio_reset(DeviceState *d)
 proxy->guest_page_shift = 0;
 }
 
+static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool
assign,
+  bool with_irqfd)
+{
+VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
+VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
+VirtQueue *vq = virtio_get_queue(vdev, n);
+EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
+
+if (assign) {
+int r = event_notifier_init(notifier, 0);
+if (r < 0) {
+return r;
+}
+virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
+} else {
+virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
+event_notifier_cleanup(notifier);
+}
+
+if (vdc->guest_notifier_mask) {
+vdc->guest_notifier_mask(vdev, n, !assign);
+}
+
+return 0;
+}
+
+static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
+   bool assign)
+{
+VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
+VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+/* TODO: need to check if kvm-arm supports irqfd */
+bool with_irqfd = false;
+int r, n;
+
+nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX);
+
+for (n = 0; n < nvqs; n++) {
+if (!virtio_queue_get_num(vdev, n)) {
+break;
+}
+
+r = virtio_mmio_set_guest_notifier(d, n, assign, with_irqfd);
+if (r < 0) {
+goto assign_error;
+}
+}
+
+return 0;
+
+assign_error:
+/* We get here on assignment failure. Recover by undoing for VQs 0 ..
n. */
+assert(assign);
+while (--n >= 0) {
+virtio_mmio_set_guest_notifier(d, n, !assign, false);
+}
+return r;
+}
+
 static int virtio_mmio_set_host_notifier(DeviceState *opaque, int n,
  bool assign)
 {
@@ -471,6 +531,7 @@ static void virtio_mmio_bus_class_init(ObjectClass
*klass, void *data)
 k->save_config = virtio_mmio_save_config;
 k->load_config = virtio_mmio_load_config;
 k->set_host_notifier = virtio_mmio_set_host_notifier;
+k->set_guest_notifiers = virtio_mmio_set_guest_notifiers;
 k->get_features = virtio_mmio_get_features;
 k->device_plugged = virtio_mmio_device_plugged;
 k->has_variable_vring_alignment = true;
-- 
1.9.5.msysgit.0

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia





Re: [Qemu-devel] [RFC] ARM/ARM64: KVM: Implement KVM_FLUSH_DCACHE_GPA ioctl

2015-05-07 Thread Jérémy Fanguède
On Wed, May 6, 2015 at 4:12 PM, Christoffer Dall
 wrote:
> Hi Jérémy,
>
> On Tue, May 05, 2015 at 11:13:11AM +0200, Jérémy Fanguède wrote:
>> To maintain cache coherency on ARM, we may need a mechanism to flush
>> the data cache.
>
> In addition to generally just making this functionality available (see
> below), do you have an actual use case in mind for this?  To solve the
> VGA issue, for example, we already have a patch series from Drew trying
> to address this.  Does that not work for you?
>
> There was a long discussion about this here:
> https://lists.cs.columbia.edu/pipermail/kvmarm/2015-February/013593.html
>
> Drew then created a patch set, here:
> https://lists.nongnu.org/archive/html/qemu-devel/2015-03/msg01254.html
>
> and replied to himself, here:
> https://www.marc.info/?l=android-virt&m=142670523929132&w=3
>
> Which basically says that he doesn't like having to do flushes all over
> QEMU (IIUC), so he sent this version instead:
> https://lists.cs.columbia.edu/pipermail/kvmarm/2015-March/014027.html
>
> Which he now said he'd respin.

In fact, I used this ioctl in pairs with this QEMU patch series:
https://lists.nongnu.org/archive/html/qemu-devel/2015-05/msg00407.html
My current work doesn't do anything about vga ram, so vga issue
probably still persists, but it solves others issues with some
emulated devices (mainly PCI) which were failing before and now work
fine with this patch.



[Qemu-devel] [PATCH v2 3/3] virtio-mmio: start ioeventfd when status gets DRIVER_OK

2015-05-07 Thread Pavel Fedin
Signed-off-by: Ying-Shiuan Pan 
Signed-off-by: Pavel Fedin 
---
 hw/virtio/virtio-mmio.c | 47
+++
 1 file changed, 47 insertions(+)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 8756240..0ab270d 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -22,6 +22,7 @@
 #include "hw/sysbus.h"
 #include "hw/virtio/virtio.h"
 #include "qemu/host-utils.h"
+#include "sysemu/kvm.h"
 #include "hw/virtio/virtio-bus.h"
 #include "qemu/error-report.h"
 
@@ -120,6 +121,43 @@ static int
virtio_mmio_set_host_notifier_internal(VirtIOMMIOProxy *proxy,
 return r;
 }
 
+static void virtio_mmio_start_ioeventfd(VirtIOMMIOProxy *proxy)
+{
+VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+int n, r;
+
+if (!kvm_eventfds_enabled() ||
+proxy->ioeventfd_disabled ||
+proxy->ioeventfd_started) {
+return;
+}
+
+for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+if (!virtio_queue_get_num(vdev, n)) {
+continue;
+}
+
+r = virtio_mmio_set_host_notifier_internal(proxy, n, true, true);
+if (r < 0) {
+goto assign_error;
+}
+}
+proxy->ioeventfd_started = true;
+return;
+
+assign_error:
+while (--n >= 0) {
+if (!virtio_queue_get_num(vdev, n)) {
+continue;
+}
+
+r = virtio_mmio_set_host_notifier_internal(proxy, n, false, false);
+assert(r >= 0);
+}
+proxy->ioeventfd_started = false;
+error_report("%s: failed. Fallback to a userspace (slower).",
__func__);
+}
+
 static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy)
 {
 int r;
@@ -318,7 +356,16 @@ static void virtio_mmio_write(void *opaque, hwaddr
offset, uint64_t value,
 virtio_update_irq(vdev);
 break;
 case VIRTIO_MMIO_STATUS:
+if (!(value & VIRTIO_CONFIG_S_DRIVER_OK)) {
+virtio_mmio_stop_ioeventfd(proxy);
+}
+
 virtio_set_status(vdev, value & 0xff);
+
+if (value & VIRTIO_CONFIG_S_DRIVER_OK) {
+virtio_mmio_start_ioeventfd(proxy);
+}
+
 if (vdev->status == 0) {
 virtio_reset(vdev);
 }
-- 
1.9.5.msysgit.0

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia





Re: [Qemu-devel] [PATCH v3 0/3] Introduce eventfd support for virtio-mmio

2015-05-07 Thread Shannon Zhao
Hi Pavel,

Have you noticed below thread? This thread is based on the patchset from
Ying-Shiuan Pan.

http://lists.gnu.org/archive/html/qemu-devel/2014-11/msg00594.html


On 2015/5/7 18:46, Pavel Fedin wrote:
>  Hello!
> 
>  This is updated version of my eventfd for virtio-mmio patch. Style notes
> have been considered, hopefully it's OK now.
>  It's now 3 parts instead of 4, because the last one was actually a small
> fix, i decided to merge it with no 3.
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
> 
> 

-- 
Shannon



[Qemu-devel] [PATCH] glib-compat.h: change assert to g_assert

2015-05-07 Thread Michael Tokarev
include/glib-compat.h defines a bunch of functions based on glib primitives,
and uses assert() without including assert.h.  Replace assert() with
g_assert() to make the file more self-contained, and to fix compilation
breakage after 28507a415a9b1e.

Reported-by: Laurent Desnogues 
Signed-off-by: Michael Tokarev 
---
 include/glib-compat.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/glib-compat.h b/include/glib-compat.h
index 011352b..28d9f15 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -115,7 +115,7 @@ static inline void g_mutex_init(CompatGMutex *mutex)
 
 static inline void g_mutex_clear(CompatGMutex *mutex)
 {
-assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
+g_assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
 if (mutex->once.retval) {
 g_mutex_free((GMutex *) mutex->once.retval);
 }
@@ -155,7 +155,7 @@ static inline void g_cond_init(CompatGCond *cond)
 
 static inline void g_cond_clear(CompatGCond *cond)
 {
-assert(cond->once.status != G_ONCE_STATUS_PROGRESS);
+g_assert(cond->once.status != G_ONCE_STATUS_PROGRESS);
 if (cond->once.retval) {
 g_cond_free((GCond *) cond->once.retval);
 }
@@ -164,7 +164,7 @@ static inline void g_cond_clear(CompatGCond *cond)
 
 static inline void (g_cond_wait)(CompatGCond *cond, CompatGMutex *mutex)
 {
-assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
+g_assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
 g_once(&cond->once, do_g_cond_new, NULL);
 g_cond_wait((GCond *) cond->once.retval, (GMutex *) mutex->once.retval);
 }
-- 
2.1.4




Re: [Qemu-devel] [RFC] ARM/ARM64: KVM: Implement KVM_FLUSH_DCACHE_GPA ioctl

2015-05-07 Thread Christoffer Dall
On Thu, May 07, 2015 at 12:50:50PM +0200, Jérémy Fanguède wrote:
> On Wed, May 6, 2015 at 4:12 PM, Christoffer Dall
>  wrote:
> > Hi Jérémy,
> >
> > On Tue, May 05, 2015 at 11:13:11AM +0200, Jérémy Fanguède wrote:
> >> To maintain cache coherency on ARM, we may need a mechanism to flush
> >> the data cache.
> >
> > In addition to generally just making this functionality available (see
> > below), do you have an actual use case in mind for this?  To solve the
> > VGA issue, for example, we already have a patch series from Drew trying
> > to address this.  Does that not work for you?
> >
> > There was a long discussion about this here:
> > https://lists.cs.columbia.edu/pipermail/kvmarm/2015-February/013593.html
> >
> > Drew then created a patch set, here:
> > https://lists.nongnu.org/archive/html/qemu-devel/2015-03/msg01254.html
> >
> > and replied to himself, here:
> > https://www.marc.info/?l=android-virt&m=142670523929132&w=3
> >
> > Which basically says that he doesn't like having to do flushes all over
> > QEMU (IIUC), so he sent this version instead:
> > https://lists.cs.columbia.edu/pipermail/kvmarm/2015-March/014027.html
> >
> > Which he now said he'd respin.
> 
> In fact, I used this ioctl in pairs with this QEMU patch series:
> https://lists.nongnu.org/archive/html/qemu-devel/2015-05/msg00407.html
> My current work doesn't do anything about vga ram, so vga issue
> probably still persists, but it solves others issues with some
> emulated devices (mainly PCI) which were failing before and now work
> fine with this patch.

Why does Drew's approach not work and your approach works here?  What is
the case that we haven't though about yet?

-Christoffer



[Qemu-devel] [PATCH RFC 0/2] virt bare-metal payload infrastructure with atomic test case

2015-05-07 Thread Alexander Spyridakis
This series implements a bare-metal test payload for the ARM and AARCH64 virt
machine models. With the new direction of TCG to finally get multi-threaded
capabilities, simple and easily deployed tests are needed, to reproduce race
conditions and intuitively debug QEMU's TCG internals.

The goal of the series is to provide an easy way to create SMP guest test cases
with minimal initialization. In its current state the provided features are,
SMP functionality through PSCI calls, a simple spinlock test-case, and
a minimal printf implementation based on the multiboot test. Parts of this
payload have been also tested with normal hosts, as well as KVM guests.

For the example spinlock test, racing errors could not be reproduced in
the default single-threaded TCG, even with a non-atomic lock. In KVM the
expected behaviour of no errors with regular locks, and some errors with
a non-atomic lock was observed. Next steps are to test multi-threaded TCG
with this kind of payloads, extend the infrastructure to more complex and
sensitive test cases, as well as support different architectures.

This work has been sponsored by Huawei Technologies Dusseldorf GmbH.

Alexander Spyridakis (2):
  atomic-test: Implement ARM and AARCH64 basic bare-metal infrastructure
  atomic-test: Add spinlock test case

 tests/atomic-test/Makefile  |  66 +++
 tests/atomic-test/helpers.c | 105 +
 tests/atomic-test/helpers.h |  48 ++
 tests/atomic-test/link.ld.S |  19 ++
 tests/atomic-test/main.c|  65 ++
 tests/atomic-test/printf.c  | 157 
 tests/atomic-test/start.S   |  54 +++
 7 files changed, 514 insertions(+)
 create mode 100644 tests/atomic-test/Makefile
 create mode 100644 tests/atomic-test/helpers.c
 create mode 100644 tests/atomic-test/helpers.h
 create mode 100644 tests/atomic-test/link.ld.S
 create mode 100644 tests/atomic-test/main.c
 create mode 100644 tests/atomic-test/printf.c
 create mode 100644 tests/atomic-test/start.S

-- 
2.1.4




[Qemu-devel] [PATCH 2/2] atomic-test: Add spinlock test case

2015-05-07 Thread Alexander Spyridakis
Sample spinlock test case with the option to implement the spinlock
by means of GCC atomic instructions or unsafe memory operations.
Additionally, printf is wrapped around a spinlock to avoid concurrent
access to the serial device.

Suggested-by: Jani Kokkonen 
Suggested-by: Claudio Fontana 
Signed-off-by: Alexander Spyridakis 
---
 tests/atomic-test/Makefile  |  3 +++
 tests/atomic-test/helpers.c | 21 +
 tests/atomic-test/helpers.h | 12 
 tests/atomic-test/main.c| 35 ++-
 tests/atomic-test/printf.c  |  5 +
 5 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/tests/atomic-test/Makefile b/tests/atomic-test/Makefile
index 094e01a..d1e992d 100644
--- a/tests/atomic-test/Makefile
+++ b/tests/atomic-test/Makefile
@@ -12,6 +12,9 @@ LD_SCRIPT = link.ld.S
 LIBS  = $(shell $(CC) $(CCFLAGS) -print-libgcc-file-name)
 CPPFLAGS  += -gdwarf-2 -fno-stack-protector -nostdinc -fno-builtin
 
+# Set to ATOMIC to implement spinlock test with real atomic instructions
+TEST = ATOMIC
+
 #
 # Target specific variables
 #
diff --git a/tests/atomic-test/helpers.c b/tests/atomic-test/helpers.c
index 8ac8c2c..fd2d4cf 100644
--- a/tests/atomic-test/helpers.c
+++ b/tests/atomic-test/helpers.c
@@ -82,3 +82,24 @@ void power_off(void)
 /* Shut down system */
 psci_call(PSCI_SYSTEM_OFF, 0, 0, 0);
 }
+
+void atomic_lock(int *lock_var)
+{
+while (__sync_lock_test_and_set(lock_var, 1));
+}
+
+void atomic_unlock(int *lock_var)
+{
+__sync_lock_release(lock_var);
+}
+
+void non_atomic_lock(int *lock_var)
+{
+while (*lock_var != 0);
+*lock_var = 1;
+}
+
+void non_atomic_unlock(int *lock_var)
+{
+*lock_var = 0;
+}
diff --git a/tests/atomic-test/helpers.h b/tests/atomic-test/helpers.h
index 66d440e..93036be 100644
--- a/tests/atomic-test/helpers.h
+++ b/tests/atomic-test/helpers.h
@@ -29,6 +29,18 @@
 #define PSCI_CPU_OFF   0x8402
 #define PSCI_SYSTEM_OFF0x8408
 
+#ifdef ATOMIC
+#define LOCK   atomic_lock
+#define UNLOCK atomic_unlock
+#else
+#define LOCK   non_atomic_lock
+#define UNLOCK non_atomic_unlock
+#endif
+
+int global_lock;
+int global_a;
+int global_b;
+
 int get_cpuid(void);
 void power_secondary(void);
 void power_off();
diff --git a/tests/atomic-test/main.c b/tests/atomic-test/main.c
index 72eaf59..3143f7c 100644
--- a/tests/atomic-test/main.c
+++ b/tests/atomic-test/main.c
@@ -15,9 +15,42 @@
  * along with this program.  If not, see .
  */
 
+#include "helpers.h"
+
+#define LOOP_SIZE 100
+
+void test_spinlock()
+{
+int i, errors = 0;
+int cpu = get_cpuid();
+
+for (i = 0; i < LOOP_SIZE; i++) {
+LOCK(&global_lock);
+
+if (global_a == (cpu + 1) % 2) {
+global_a = 1;
+global_b = 0;
+} else {
+global_a = 0;
+global_b = 1;
+}
+
+if (global_a == global_b) {
+errors++;
+}
+UNLOCK(&global_lock);
+}
+
+printf("CPU%d: Done - Errors: %d\n", cpu, errors);
+}
+
 void main(void)
 {
-printf("CPU %d on\n", get_cpuid());
+if (!get_cpuid()) {
+printf("Starting test\n");
+}
+
+test_spinlock();
 power_off();
 }
 
diff --git a/tests/atomic-test/printf.c b/tests/atomic-test/printf.c
index 7c40d37..78a9e54 100644
--- a/tests/atomic-test/printf.c
+++ b/tests/atomic-test/printf.c
@@ -17,6 +17,8 @@
  * along with this program.  If not, see .
  */
 
+#include "helpers.h"
+
 #define UARTDR  UART_PHYS
 #define UARTFR  0x18
 #define UARTFR_TXFF (1 << 5)
@@ -28,6 +30,7 @@ typedef __builtin_va_list   va_list;
 
 int *uart_phys = (int *)(UART_PHYS);
 int *uart_busy = (int *)(UART_PHYS + UARTFR);
+int printf_lock;
 
 static void putc(char c)
 {
@@ -72,6 +75,7 @@ void printf(const char *fmt, ...)
 int alt_form;
 unsigned long long val;
 
+atomic_lock(&printf_lock);
 va_start(ap, fmt);
 
 for (; *fmt; fmt++) {
@@ -149,4 +153,5 @@ void printf(const char *fmt, ...)
 }
 
 va_end(ap);
+atomic_unlock(&printf_lock);
 }
-- 
2.1.4




[Qemu-devel] [PATCH RFC 1/2] atomic-test: Implement ARM and AARCH64 basic bare-metal infrastructure

2015-05-07 Thread Alexander Spyridakis
Minimal payload initialization for the virt machine model.
Setup a stack and jump to C code, where CPU0 will boot any
discovered secondary cores through PSCI. Immediately after
all cores are turned-off and the guest is powered down.

Added printf functionality is based on the multiboot test. In a
similar manner this test is standalone and not part of 'make check'.

Suggested-by: Jani Kokkonen 
Suggested-by: Claudio Fontana 
Signed-off-by: Alexander Spyridakis 
---
 tests/atomic-test/Makefile  |  63 ++
 tests/atomic-test/helpers.c |  84 
 tests/atomic-test/helpers.h |  36 +++
 tests/atomic-test/link.ld.S |  19 ++
 tests/atomic-test/main.c|  32 ++
 tests/atomic-test/printf.c  | 152 
 tests/atomic-test/start.S   |  54 
 7 files changed, 440 insertions(+)
 create mode 100644 tests/atomic-test/Makefile
 create mode 100644 tests/atomic-test/helpers.c
 create mode 100644 tests/atomic-test/helpers.h
 create mode 100644 tests/atomic-test/link.ld.S
 create mode 100644 tests/atomic-test/main.c
 create mode 100644 tests/atomic-test/printf.c
 create mode 100644 tests/atomic-test/start.S

diff --git a/tests/atomic-test/Makefile b/tests/atomic-test/Makefile
new file mode 100644
index 000..094e01a
--- /dev/null
+++ b/tests/atomic-test/Makefile
@@ -0,0 +1,63 @@
+#
+# Global variables, sources and tools
+#
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+
+S_OBJS= start.o
+C_OBJS= main.o printf.o helpers.o
+H_DEPS= helpers.h
+LD_SCRIPT = link.ld.S
+
+LIBS  = $(shell $(CC) $(CCFLAGS) -print-libgcc-file-name)
+CPPFLAGS  += -gdwarf-2 -fno-stack-protector -nostdinc -fno-builtin
+
+#
+# Target specific variables
+#
+clean: export DIRS = build-virt build-virt64
+
+virt:   export CPPFLAGS += -march=armv7-a
+virt64: export CPPFLAGS += -march=armv8-a -mgeneral-regs-only -mstrict-align
+
+virt:   export CROSS_COMPILE ?= arm-none-eabi-
+virt64: export CROSS_COMPILE ?= aarch64-linux-gnu-
+
+virt:   export ARCH = ARCH_ARM
+virt64: export ARCH = ARCH_AARCH64
+
+virt virt64: export UART_PHYS = 0x0900
+virt virt64: export ENTRY_POINT = 0x4000
+
+virt virt64: export O_DIR = build-$@/
+virt virt64: export IMAGE = $(O_DIR)image-$@.axf
+
+#
+# Target build rules
+#
+all: virt virt64
+
+clean:
+   rm -rf $(DIRS)
+
+virt virt64:
+   mkdir -p $(O_DIR)
+   @$(MAKE) $(IMAGE) --no-print-directory
+
+$(IMAGE): $(addprefix $(O_DIR), $(S_OBJS)) \
+  $(addprefix $(O_DIR), $(C_OBJS)) $(H_DEPS) $(O_DIR)link.ld Makefile
+   $(LD) -o $@ $(addprefix $(O_DIR), $(S_OBJS)) \
+  $(addprefix $(O_DIR), $(C_OBJS)) $(LIBS) \
+  --script=$(O_DIR)link.ld -Map $(O_DIR)system.map
+
+$(O_DIR)link.ld: $(LD_SCRIPT)
+   $(CC) -DENTRY_POINT=$(ENTRY_POINT) -D$(ARCH) $(CPPFLAGS) -E -P -C -o $@ 
$<
+
+$(O_DIR)%.o: %.c $(H_DEPS)
+   $(CC) -DENTRY_POINT=$(ENTRY_POINT) \
+  -DUART_PHYS=$(UART_PHYS) -D$(ARCH) $(CPPFLAGS) -c -o $@ $<
+
+$(O_DIR)%.o: %.S $(H_DEPS)
+   $(CC) -D$(ARCH) $(CPPFLAGS) -c -o $@ $<
+
+.PHONY: all clean virt virt64
diff --git a/tests/atomic-test/helpers.c b/tests/atomic-test/helpers.c
new file mode 100644
index 000..8ac8c2c
--- /dev/null
+++ b/tests/atomic-test/helpers.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 Virtual Open Systems SAS
+ * Author: Alexander Spyridakis 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "helpers.h"
+
+#ifdef ARCH_ARM
+__asm__(".arch_extension virt");
+
+int get_cpuid(void)
+{
+int cpu;
+asm volatile ("mrc p15, 0, %0, c0, c0, 5; and %0, %0, #15\n" : "=r"(cpu));
+return cpu;
+}
+
+int psci_call(int psci_function, int arg0, int arg1, int arg2)
+{
+int ret;
+asm volatile ("hvc #0; mov %0, r0\n" : "=r" (ret));
+return ret;
+}
+#elif ARCH_AARCH64
+int get_cpuid(void)
+{
+int cpu;
+asm volatile ("mrs %0, MPIDR_EL1; and %0, %0, #15\n" : "=r"(cpu));
+return cpu;
+}
+
+int psci_call(int psci_function, int arg0, int arg1, int arg2)
+{
+int ret;
+asm volatile ("hvc #0; mov %0, x0\n" : "=r" (ret));
+return ret;
+}
+#endif
+
+void power_secondary(void)
+{
+int ret, cpu = 1;
+
+/* Sequentially power-up all secondary cores,
+ * error means trying to wake up non existing cores */
+do { ret = psci_call(PSCI_CPU_ON, cpu++, ENTRY_POINT, 0); } while (!ret);
+}
+
+void power_off(void)
+{
+int ret, i = 1;
+int

Re: [Qemu-devel] [PULL 00/15] migration pull request

2015-05-07 Thread Juan Quintela
Eric Blake  wrote:
> On 05/06/2015 12:37 PM, Peter Maydell wrote:
>> On 6 May 2015 at 18:49, Juan Quintela  wrote:
>>> Hi
>>>
>
>> 
>> Fails to build on 32 bit, I'm afraid:
>> 
>> /root/qemu/arch_init.c: In function ‘do_data_decompress’:
>> /root/qemu/arch_init.c:1486:28: error: passing argument 2 of
>> ‘uncompress’ from incompatible pointer type [-Werror]
>
> Then you might as well also fix up the .json file references to 2.3 on
> the respin.

Done both things.

Sorry for the noise.

Thanks,



Re: [Qemu-devel] [PATCH] migration: Fix migration state update issue

2015-05-07 Thread Dr. David Alan Gilbert
* Liang Li (liang.z...@intel.com) wrote:
> If live migration is very fast and can be completed in 1 second,
> the dirty_sync_count of MigrationState will not be updated.
> Then you will see "dirty sync count: 0" in qemu monitor even if
> the actual dirty sync count is not 0.
> 
> Signed-off-by: Liang Li 
> ---
>  arch_init.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch_init.c b/arch_init.c
> index 4c8fcee..a48f575 100644
> --- a/arch_init.c
> +++ b/arch_init.c
> @@ -599,8 +599,8 @@ static void migration_bitmap_sync(void)
>  s->dirty_bytes_rate = s->dirty_pages_rate * TARGET_PAGE_SIZE;
>  start_time = end_time;
>  num_dirty_pages_period = 0;
> -s->dirty_sync_count = bitmap_sync_count;
>  }
> +s->dirty_sync_count = bitmap_sync_count;
>  }

Yes, makes sense.
(An interesting question is why there needs to be a separate bitmap_sync_count
variable that's separate from s->dirty_sync_count)

Reviewed-by: Dr. David Alan Gilbert 

Dave

>  
>  /**
> -- 
> 1.9.1
> 
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH] migration: Fix migration state update issue

2015-05-07 Thread Juan Quintela
Liang Li  wrote:
> If live migration is very fast and can be completed in 1 second,
> the dirty_sync_count of MigrationState will not be updated.
> Then you will see "dirty sync count: 0" in qemu monitor even if
> the actual dirty sync count is not 0.
>
> Signed-off-by: Liang Li 

Reviewed-by: Juan Quintela 

Added to new pull request, thanks.


> ---
>  arch_init.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch_init.c b/arch_init.c
> index 4c8fcee..a48f575 100644
> --- a/arch_init.c
> +++ b/arch_init.c
> @@ -599,8 +599,8 @@ static void migration_bitmap_sync(void)
>  s->dirty_bytes_rate = s->dirty_pages_rate * TARGET_PAGE_SIZE;
>  start_time = end_time;
>  num_dirty_pages_period = 0;
> -s->dirty_sync_count = bitmap_sync_count;
>  }
> +s->dirty_sync_count = bitmap_sync_count;
>  }
>  
>  /**



Re: [Qemu-devel] [PATCH v3 0/3] Introduce eventfd support for virtio-mmio

2015-05-07 Thread Pavel Fedin
 Hello!

> Have you noticed below thread? This thread is based on the patchset from
Ying-
> Shiuan Pan.
> 
> http://lists.gnu.org/archive/html/qemu-devel/2014-11/msg00594.html

 Yes, of course. Actually my set is based on that one, it's just updated
against current master and improved a little bit. In v1 series cover letter
i wrote about that, just for v2 i decided not to retype the whole intro.
Perhaps that was a bad idea.

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia





[Qemu-devel] [PATCH v2 2/2] semihosting: add --semihosting-config arg sub-argument

2015-05-07 Thread Leon Alrae
Add new "arg" sub-argument to the --semihosting-config allowing to pass
multiple input argument separately. It is required for example by UHI
semihosting to construct argc and argv.

Signed-off-by: Leon Alrae 
---
 include/exec/semihost.h | 12 
 qemu-options.hx |  8 +---
 vl.c| 33 +
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/include/exec/semihost.h b/include/exec/semihost.h
index c2f0bcb..6e4e8c0 100644
--- a/include/exec/semihost.h
+++ b/include/exec/semihost.h
@@ -36,9 +36,21 @@ static inline SemihostingTarget semihosting_get_target(void)
 {
 return SEMIHOSTING_TARGET_AUTO;
 }
+
+static inline const char *semihosting_get_arg(int i)
+{
+return NULL;
+}
+
+static inline int semihosting_get_argc(void)
+{
+return 0;
+}
 #else
 bool semihosting_enabled(void);
 SemihostingTarget semihosting_get_target(void);
+const char *semihosting_get_arg(int i);
+int semihosting_get_argc(void);
 #endif
 
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index ec356f6..ed2a7e8 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3296,14 +3296,16 @@ STEXI
 Enable semihosting mode (ARM, M68K, Xtensa only).
 ETEXI
 DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
-"-semihosting-config [enable=on|off,]target=native|gdb|auto   semihosting 
configuration\n",
+"-semihosting-config 
[enable=on|off][,target=native|gdb|auto][,arg=str[,...]]\n" \
+"semihosting configuration\n",
 QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
 STEXI
-@item -semihosting-config [enable=on|off,]target=native|gdb|auto
+@item -semihosting-config 
[enable=on|off][,target=native|gdb|auto][,arg=str[,...]]
 @findex -semihosting-config
 Enable semihosting and define where the semihosting calls will be addressed,
 to QEMU (@code{native}) or to GDB (@code{gdb}). The default is @code{auto}, 
which means
-@code{gdb} during debug sessions and @code{native} otherwise (ARM, M68K, 
Xtensa only).
+@code{gdb} during debug sessions and @code{native} otherwise. The @var{arg} 
allows to
+pass input arguments, can be used multiple times to build up a list (ARM, 
M68K, Xtensa only)
 ETEXI
 DEF("old-param", 0, QEMU_OPTION_old_param,
 "-old-param  old param mode\n", QEMU_ARCH_ARM)
diff --git a/vl.c b/vl.c
index f3319a9..c8ac1e6 100644
--- a/vl.c
+++ b/vl.c
@@ -486,6 +486,9 @@ static QemuOptsList qemu_semihosting_config_opts = {
 }, {
 .name = "target",
 .type = QEMU_OPT_STRING,
+}, {
+.name = "arg",
+.type = QEMU_OPT_STRING,
 },
 { /* end of list */ }
 },
@@ -1230,6 +1233,8 @@ static void configure_msg(QemuOpts *opts)
 typedef struct SemihostingConfig {
 bool enabled;
 SemihostingTarget target;
+const char **argv;
+int argc;
 } SemihostingConfig;
 
 static SemihostingConfig semihosting;
@@ -1244,6 +1249,31 @@ SemihostingTarget semihosting_get_target(void)
 return semihosting.target;
 }
 
+const char *semihosting_get_arg(int i)
+{
+if (i >= semihosting.argc) {
+return NULL;
+}
+
+return semihosting.argv[i];
+}
+
+int semihosting_get_argc(void)
+{
+return semihosting.argc;
+}
+
+static int add_semihosting_arg(const char *name, const char *val, void *opaque)
+{
+SemihostingConfig *s = opaque;
+if (strcmp(name, "arg") == 0) {
+s->argc++;
+s->argv = g_realloc(s->argv, s->argc * sizeof(void *));
+s->argv[s->argc - 1] = val;
+}
+return 0;
+}
+
 /***/
 /* USB devices */
 
@@ -3592,6 +3622,9 @@ int main(int argc, char **argv, char **envp)
 } else {
 semihosting.target = SEMIHOSTING_TARGET_AUTO;
 }
+/* Set semihosting argument count and vector */
+qemu_opt_foreach(opts, add_semihosting_arg,
+ &semihosting, 0);
 } else {
 fprintf(stderr, "Unsupported semihosting-config %s\n",
 optarg);



[Qemu-devel] [PATCH v2 1/2] semihosting: create SemihostingConfig structure and semihost.h

2015-05-07 Thread Leon Alrae
Remove semihosting_enabled and semihosting_target and replace them with
SemihostingConfig structure containing equivalent fields. The structure
is defined in vl.c where it is actually set.

Also introduce separate header file include/exec/semihost.h allowing to
access semihosting config related stuff from target specific semihosting
code.

Signed-off-by: Leon Alrae 
---
 gdbstub.c |  8 
 include/exec/gdbstub.h|  6 --
 include/exec/semihost.h   | 44 
 include/sysemu/sysemu.h   |  1 -
 target-arm/helper.c   |  7 ---
 target-lm32/helper.c  |  3 ++-
 target-m68k/op_helper.c   |  5 ++---
 target-xtensa/translate.c |  3 ++-
 vl.c  | 38 +-
 9 files changed, 87 insertions(+), 28 deletions(-)
 create mode 100644 include/exec/semihost.h

diff --git a/gdbstub.c b/gdbstub.c
index 8abcb8a..9931d81 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -40,6 +40,7 @@
 #include "cpu.h"
 #include "qemu/sockets.h"
 #include "sysemu/kvm.h"
+#include "exec/semihost.h"
 
 static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
  uint8_t *buf, int len, bool is_write)
@@ -317,8 +318,6 @@ static GDBState *gdbserver_state;
 
 bool gdb_has_xml;
 
-int semihosting_target = SEMIHOSTING_TARGET_AUTO;
-
 #ifdef CONFIG_USER_ONLY
 /* XXX: This is not thread safe.  Do we care?  */
 static int gdbserver_fd = -1;
@@ -356,10 +355,11 @@ static enum {
 /* Decide if either remote gdb syscalls or native file IO should be used. */
 int use_gdb_syscalls(void)
 {
-if (semihosting_target == SEMIHOSTING_TARGET_NATIVE) {
+SemihostingTarget target = semihosting_get_target();
+if (target == SEMIHOSTING_TARGET_NATIVE) {
 /* -semihosting-config target=native */
 return false;
-} else if (semihosting_target == SEMIHOSTING_TARGET_GDB) {
+} else if (target == SEMIHOSTING_TARGET_GDB) {
 /* -semihosting-config target=gdb */
 return true;
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index c633248..a608a26 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -95,10 +95,4 @@ extern bool gdb_has_xml;
 /* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */
 extern const char *const xml_builtin[][2];
 
-/* Command line option defining whether semihosting should go via gdb or not */
-extern int semihosting_target;
-#define SEMIHOSTING_TARGET_AUTO 0
-#define SEMIHOSTING_TARGET_NATIVE   1
-#define SEMIHOSTING_TARGET_GDB  2
-
 #endif
diff --git a/include/exec/semihost.h b/include/exec/semihost.h
new file mode 100644
index 000..c2f0bcb
--- /dev/null
+++ b/include/exec/semihost.h
@@ -0,0 +1,44 @@
+/*
+ * Semihosting support
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef SEMIHOST_H
+#define SEMIHOST_H
+
+typedef enum SemihostingTarget {
+SEMIHOSTING_TARGET_AUTO = 0,
+SEMIHOSTING_TARGET_NATIVE,
+SEMIHOSTING_TARGET_GDB
+} SemihostingTarget;
+
+#ifdef CONFIG_USER_ONLY
+static inline bool semihosting_enabled(void)
+{
+return true;
+}
+
+static inline SemihostingTarget semihosting_get_target(void)
+{
+return SEMIHOSTING_TARGET_AUTO;
+}
+#else
+bool semihosting_enabled(void);
+SemihostingTarget semihosting_get_target(void);
+#endif
+
+#endif
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 8a52934..bf552a7 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -125,7 +125,6 @@ extern int cursor_hide;
 extern int graphic_rotate;
 extern int no_quit;
 extern int no_shutdown;
-extern int semihosting_enabled;
 extern int old_param;
 extern int boot_menu;
 extern bool boot_strict;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f8f8d76..f5a9897 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -10,6 +10,7 @@
 #include "exec/cpu_ldst.h"
 #include "arm_ldst.h"
 #include  /* For crc32 */
+#include "exec/semihost.h"
 
 #ifndef CONFIG_USER_ONLY
 static inline int get_phys_addr(CPUARMState *env, target_ulong address,
@@ -4401,7 +4402,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
 return;
 case EXCP_BKPT:
-if (semihosting_enabled) {
+if (s

[Qemu-devel] [PULL 01/16] docs: Add a doc about multiple thread compression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Give some details about the multiple thread (de)compression and
how to use it in live migration.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 docs/multi-thread-compression.txt | 149 ++
 1 file changed, 149 insertions(+)
 create mode 100644 docs/multi-thread-compression.txt

diff --git a/docs/multi-thread-compression.txt 
b/docs/multi-thread-compression.txt
new file mode 100644
index 000..3d477c3
--- /dev/null
+++ b/docs/multi-thread-compression.txt
@@ -0,0 +1,149 @@
+Use multiple thread (de)compression in live migration
+=
+Copyright (C) 2015 Intel Corporation
+Author: Liang Li 
+
+This work is licensed under the terms of the GNU GPLv2 or later. See
+the COPYING file in the top-level directory.
+
+Contents:
+=
+* Introduction
+* When to use
+* Performance
+* Usage
+* TODO
+
+Introduction
+
+Instead of sending the guest memory directly, this solution will
+compress the RAM page before sending; after receiving, the data will
+be decompressed. Using compression in live migration can help
+to reduce the data transferred about 60%, this is very useful when the
+bandwidth is limited, and the total migration time can also be reduced
+about 70% in a typical case. In addition to this, the VM downtime can be
+reduced about 50%. The benefit depends on data's compressibility in VM.
+
+The process of compression will consume additional CPU cycles, and the
+extra CPU cycles will increase the migration time. On the other hand,
+the amount of data transferred will decrease; this factor can reduce
+the total migration time. If the process of the compression is quick
+enough, then the total migration time can be reduced, and multiple
+thread compression can be used to accelerate the compression process.
+
+The decompression speed of Zlib is at least 4 times as quick as
+compression, if the source and destination CPU have equal speed,
+keeping the compression thread count 4 times the decompression
+thread count can avoid resource waste.
+
+Compression level can be used to control the compression speed and the
+compression ratio. High compression ratio will take more time, level 0
+stands for no compression, level 1 stands for the best compression
+speed, and level 9 stands for the best compression ratio. Users can
+select a level number between 0 and 9.
+
+
+When to use the multiple thread compression in live migration
+=
+Compression of data will consume extra CPU cycles; so in a system with
+high overhead of CPU, avoid using this feature. When the network
+bandwidth is very limited and the CPU resource is adequate, use of
+multiple thread compression will be very helpful. If both the CPU and
+the network bandwidth are adequate, use of multiple thread compression
+can still help to reduce the migration time.
+
+Performance
+===
+Test environment:
+
+CPU: Intel(R) Xeon(R) CPU E5-2680 0 @ 2.70GHz
+Socket Count: 2
+RAM: 128G
+NIC: Intel I350 (10/100/1000Mbps)
+Host OS: CentOS 7 64-bit
+Guest OS: RHEL 6.5 64-bit
+Parameter: qemu-system-x86_64 -enable-kvm -smp 4 -m 4096
+ /share/ia32e_rhel6u5.qcow -monitor stdio
+
+There is no additional application is running on the guest when doing
+the test.
+
+
+Speed limit: 1000Gb/s
+---
+| original  | compress thread: 8
+|   way | decompress thread: 2
+|   | compression level: 1
+---
+total time(msec):   |   |  1833
+---
+downtime(msec): |100|   27
+---
+transferred ram(kB):|  363536   | 107819
+---
+throughput(mbps):   |  893.73   | 482.22
+---
+total ram(kB):  |  4211524  | 4211524
+---
+
+There is an application running on the guest which write random numbers
+to RAM block areas periodically.
+
+Speed limit: 1000Gb/s
+---
+| original  | compress thread: 8
+|   way | decompress thread: 2
+|   | compression level: 1
+---
+total time(msec):   |   37369   | 15989
+---
+downtime(msec): |337|  173
+---
+transferred ram(kB):|  4274143  | 1699824
+-

[Qemu-devel] [PULL 03/16] migration: Add the framework of multi-thread decompression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Add the code to create and destroy the multiple threads those will be
used to do data decompression. Left some functions empty just to keep
clearness, and the code will be added later.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 arch_init.c   | 77 +++
 include/migration/migration.h |  4 +++
 migration/migration.c | 19 +++
 3 files changed, 100 insertions(+)

diff --git a/arch_init.c b/arch_init.c
index 179c58c..8749481 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifndef _WIN32
 #include 
 #include 
@@ -127,6 +128,7 @@ static uint64_t bitmap_sync_count;
 #define RAM_SAVE_FLAG_CONTINUE 0x20
 #define RAM_SAVE_FLAG_XBZRLE   0x40
 /* 0x80 is reserved in migration.h start with 0x100 next */
+#define RAM_SAVE_FLAG_COMPRESS_PAGE0x100

 static struct defconfig_file {
 const char *filename;
@@ -321,9 +323,18 @@ struct CompressParam {
 };
 typedef struct CompressParam CompressParam;

+struct DecompressParam {
+/* To be done */
+};
+typedef struct DecompressParam DecompressParam;
+
 static CompressParam *comp_param;
 static QemuThread *compress_threads;
 static bool quit_comp_thread;
+static bool quit_decomp_thread;
+static DecompressParam *decomp_param;
+static QemuThread *decompress_threads;
+static uint8_t *compressed_data_buf;

 static void *do_data_compress(void *opaque)
 {
@@ -1203,10 +1214,59 @@ void ram_handle_compressed(void *host, uint8_t ch, 
uint64_t size)
 }
 }

+static void *do_data_decompress(void *opaque)
+{
+while (!quit_decomp_thread) {
+/* To be done */
+}
+
+return NULL;
+}
+
+void migrate_decompress_threads_create(void)
+{
+int i, thread_count;
+
+thread_count = migrate_decompress_threads();
+decompress_threads = g_new0(QemuThread, thread_count);
+decomp_param = g_new0(DecompressParam, thread_count);
+compressed_data_buf = g_malloc0(compressBound(TARGET_PAGE_SIZE));
+quit_decomp_thread = false;
+for (i = 0; i < thread_count; i++) {
+qemu_thread_create(decompress_threads + i, "decompress",
+   do_data_decompress, decomp_param + i,
+   QEMU_THREAD_JOINABLE);
+}
+}
+
+void migrate_decompress_threads_join(void)
+{
+int i, thread_count;
+
+quit_decomp_thread = true;
+thread_count = migrate_decompress_threads();
+for (i = 0; i < thread_count; i++) {
+qemu_thread_join(decompress_threads + i);
+}
+g_free(decompress_threads);
+g_free(decomp_param);
+g_free(compressed_data_buf);
+decompress_threads = NULL;
+decomp_param = NULL;
+compressed_data_buf = NULL;
+}
+
+static void decompress_data_with_multi_threads(uint8_t *compbuf,
+   void *host, int len)
+{
+/* To be done */
+}
+
 static int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
 int flags = 0, ret = 0;
 static uint64_t seq_iter;
+int len = 0;

 seq_iter++;

@@ -1286,6 +1346,23 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 }
 qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
 break;
+case RAM_SAVE_FLAG_COMPRESS_PAGE:
+host = host_from_stream_offset(f, addr, flags);
+if (!host) {
+error_report("Invalid RAM offset " RAM_ADDR_FMT, addr);
+ret = -EINVAL;
+break;
+}
+
+len = qemu_get_be32(f);
+if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) {
+error_report("Invalid compressed data length: %d", len);
+ret = -EINVAL;
+break;
+}
+qemu_get_buffer(f, compressed_data_buf, len);
+decompress_data_with_multi_threads(compressed_data_buf, host, len);
+break;
 case RAM_SAVE_FLAG_XBZRLE:
 host = host_from_stream_offset(f, addr, flags);
 if (!host) {
diff --git a/include/migration/migration.h b/include/migration/migration.h
index a3ebbf6..d4a1062 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -51,6 +51,7 @@ struct MigrationState
 QEMUBH *cleanup_bh;
 QEMUFile *file;
 int compress_thread_count;
+int decompress_thread_count;
 int compress_level;

 int state;
@@ -108,6 +109,8 @@ MigrationState *migrate_get_current(void);

 void migrate_compress_threads_create(void);
 void migrate_compress_threads_join(void);
+void migrate_decompress_threads_create(void);
+void migrate_decompress_threads_join(void);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_transferred(void);
 uint64_t ram_bytes_total(void);
@@ -159,6 +162,7 @@ int64_t xbzrle_cache_resize(int64_t new_size);
 bool migrate_use_compression(void);
 int migrate_co

Re: [Qemu-devel] [PATCH 4/4] semihosting: add --semihosting-config arg sub-argument

2015-05-07 Thread Liviu Ionescu

> On 07 May 2015, at 12:52, Leon Alrae  wrote:
> 
>> is it that difficult to count the "arg"s and correctly alloc the array?
> 
> This probably would require going through the list twice 

the code to iterate is already there, for other options, you just need to add a 
branch to the existing case.


regards,

Liviu





[Qemu-devel] [PULL 05/16] arch_init: Alloc and free data struct for compression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Define the data structure and variables used to do multiple thread
compression, and add the code to initialize and free them.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 35 ++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch_init.c b/arch_init.c
index 8749481..87dccef 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -319,7 +319,13 @@ static uint32_t last_version;
 static bool ram_bulk_stage;

 struct CompressParam {
-/* To be done */
+bool start;
+bool done;
+QEMUFile *file;
+QemuMutex mutex;
+QemuCond cond;
+RAMBlock *block;
+ram_addr_t offset;
 };
 typedef struct CompressParam CompressParam;

@@ -330,6 +336,14 @@ typedef struct DecompressParam DecompressParam;

 static CompressParam *comp_param;
 static QemuThread *compress_threads;
+/* comp_done_cond is used to wake up the migration thread when
+ * one of the compression threads has finished the compression.
+ * comp_done_lock is used to co-work with comp_done_cond.
+ */
+static QemuMutex *comp_done_lock;
+static QemuCond *comp_done_cond;
+/* The empty QEMUFileOps will be used by file in CompressParam */
+static const QEMUFileOps empty_ops = { };
 static bool quit_comp_thread;
 static bool quit_decomp_thread;
 static DecompressParam *decomp_param;
@@ -365,11 +379,20 @@ void migrate_compress_threads_join(void)
 thread_count = migrate_compress_threads();
 for (i = 0; i < thread_count; i++) {
 qemu_thread_join(compress_threads + i);
+qemu_fclose(comp_param[i].file);
+qemu_mutex_destroy(&comp_param[i].mutex);
+qemu_cond_destroy(&comp_param[i].cond);
 }
+qemu_mutex_destroy(comp_done_lock);
+qemu_cond_destroy(comp_done_cond);
 g_free(compress_threads);
 g_free(comp_param);
+g_free(comp_done_cond);
+g_free(comp_done_lock);
 compress_threads = NULL;
 comp_param = NULL;
+comp_done_cond = NULL;
+comp_done_lock = NULL;
 }

 void migrate_compress_threads_create(void)
@@ -383,7 +406,17 @@ void migrate_compress_threads_create(void)
 thread_count = migrate_compress_threads();
 compress_threads = g_new0(QemuThread, thread_count);
 comp_param = g_new0(CompressParam, thread_count);
+comp_done_cond = g_new0(QemuCond, 1);
+comp_done_lock = g_new0(QemuMutex, 1);
+qemu_cond_init(comp_done_cond);
+qemu_mutex_init(comp_done_lock);
 for (i = 0; i < thread_count; i++) {
+/* com_param[i].file is just used as a dummy buffer to save data, set
+ * it's ops to empty.
+ */
+comp_param[i].file = qemu_fopen_ops(NULL, &empty_ops);
+qemu_mutex_init(&comp_param[i].mutex);
+qemu_cond_init(&comp_param[i].cond);
 qemu_thread_create(compress_threads + i, "compress",
do_data_compress, comp_param + i,
QEMU_THREAD_JOINABLE);
-- 
2.4.0




[Qemu-devel] [PULL 06/16] arch_init: Add and free data struct for decompression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Define the data structure and variables used to do multiple thread
decompression, and add the code to initialize and free them.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch_init.c b/arch_init.c
index 87dccef..ebd246f 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -330,7 +330,12 @@ struct CompressParam {
 typedef struct CompressParam CompressParam;

 struct DecompressParam {
-/* To be done */
+bool start;
+QemuMutex mutex;
+QemuCond cond;
+void *des;
+uint8 *compbuf;
+int len;
 };
 typedef struct DecompressParam DecompressParam;

@@ -1266,6 +1271,9 @@ void migrate_decompress_threads_create(void)
 compressed_data_buf = g_malloc0(compressBound(TARGET_PAGE_SIZE));
 quit_decomp_thread = false;
 for (i = 0; i < thread_count; i++) {
+qemu_mutex_init(&decomp_param[i].mutex);
+qemu_cond_init(&decomp_param[i].cond);
+decomp_param[i].compbuf = g_malloc0(compressBound(TARGET_PAGE_SIZE));
 qemu_thread_create(decompress_threads + i, "decompress",
do_data_decompress, decomp_param + i,
QEMU_THREAD_JOINABLE);
@@ -1280,6 +1288,9 @@ void migrate_decompress_threads_join(void)
 thread_count = migrate_decompress_threads();
 for (i = 0; i < thread_count; i++) {
 qemu_thread_join(decompress_threads + i);
+qemu_mutex_destroy(&decomp_param[i].mutex);
+qemu_cond_destroy(&decomp_param[i].cond);
+g_free(decomp_param[i].compbuf);
 }
 g_free(decompress_threads);
 g_free(decomp_param);
-- 
2.4.0




[Qemu-devel] [PULL 02/16] migration: Add the framework of multi-thread compression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Add the code to create and destroy the multiple threads those will
be used to do data compression. Left some functions empty to keep
clearness, and the code will be added later.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 arch_init.c   | 94 ++-
 include/migration/migration.h |  8 
 migration/migration.c | 37 +
 3 files changed, 137 insertions(+), 2 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 4c8fcee..179c58c 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -316,6 +316,69 @@ static uint64_t migration_dirty_pages;
 static uint32_t last_version;
 static bool ram_bulk_stage;

+struct CompressParam {
+/* To be done */
+};
+typedef struct CompressParam CompressParam;
+
+static CompressParam *comp_param;
+static QemuThread *compress_threads;
+static bool quit_comp_thread;
+
+static void *do_data_compress(void *opaque)
+{
+while (!quit_comp_thread) {
+
+/* To be done */
+
+}
+
+return NULL;
+}
+
+static inline void terminate_compression_threads(void)
+{
+quit_comp_thread = true;
+
+/* To be done */
+}
+
+void migrate_compress_threads_join(void)
+{
+int i, thread_count;
+
+if (!migrate_use_compression()) {
+return;
+}
+terminate_compression_threads();
+thread_count = migrate_compress_threads();
+for (i = 0; i < thread_count; i++) {
+qemu_thread_join(compress_threads + i);
+}
+g_free(compress_threads);
+g_free(comp_param);
+compress_threads = NULL;
+comp_param = NULL;
+}
+
+void migrate_compress_threads_create(void)
+{
+int i, thread_count;
+
+if (!migrate_use_compression()) {
+return;
+}
+quit_comp_thread = false;
+thread_count = migrate_compress_threads();
+compress_threads = g_new0(QemuThread, thread_count);
+comp_param = g_new0(CompressParam, thread_count);
+for (i = 0; i < thread_count; i++) {
+qemu_thread_create(compress_threads + i, "compress",
+   do_data_compress, comp_param + i,
+   QEMU_THREAD_JOINABLE);
+}
+}
+
 /**
  * save_page_header: Write page header to wire
  *
@@ -693,6 +756,28 @@ static int ram_save_page(QEMUFile *f, RAMBlock* block, 
ram_addr_t offset,
 }

 /**
+ * ram_save_compressed_page: compress the given page and send it to the stream
+ *
+ * Returns: Number of pages written.
+ *
+ * @f: QEMUFile where to send the data
+ * @block: block that contains the page we want to send
+ * @offset: offset inside the block for the page
+ * @last_stage: if we are at the completion stage
+ * @bytes_transferred: increase it with the number of transferred bytes
+ */
+static int ram_save_compressed_page(QEMUFile *f, RAMBlock *block,
+ram_addr_t offset, bool last_stage,
+uint64_t *bytes_transferred)
+{
+int pages = -1;
+
+/* To be done*/
+
+return pages;
+}
+
+/**
  * ram_find_and_save_block: Finds a dirty page and sends it to f
  *
  * Called within an RCU critical section.
@@ -733,8 +818,13 @@ static int ram_find_and_save_block(QEMUFile *f, bool 
last_stage,
 ram_bulk_stage = false;
 }
 } else {
-pages = ram_save_page(f, block, offset, last_stage,
-  bytes_transferred);
+if (migrate_use_compression()) {
+pages = ram_save_compressed_page(f, block, offset, last_stage,
+ bytes_transferred);
+} else {
+pages = ram_save_page(f, block, offset, last_stage,
+  bytes_transferred);
+}

 /* if page is unmodified, continue to the next */
 if (pages > 0) {
diff --git a/include/migration/migration.h b/include/migration/migration.h
index bf09968..a3ebbf6 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -50,6 +50,8 @@ struct MigrationState
 QemuThread thread;
 QEMUBH *cleanup_bh;
 QEMUFile *file;
+int compress_thread_count;
+int compress_level;

 int state;
 MigrationParams params;
@@ -104,6 +106,8 @@ bool migration_has_finished(MigrationState *);
 bool migration_has_failed(MigrationState *);
 MigrationState *migrate_get_current(void);

+void migrate_compress_threads_create(void);
+void migrate_compress_threads_join(void);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_transferred(void);
 uint64_t ram_bytes_total(void);
@@ -152,6 +156,10 @@ int64_t migrate_xbzrle_cache_size(void);

 int64_t xbzrle_cache_resize(int64_t new_size);

+bool migrate_use_compression(void);
+int migrate_compress_level(void);
+int migrate_compress_threads(void);
+
 void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
 void ram_control

[Qemu-devel] [PULL 00/16] Migration pull request (v2)

2015-05-07 Thread Juan Quintela


Hi again

For v2

- fix 32bit compilation (as said, compiling for 64bit linux, 64bit
  windows and 32bit windows was not enough)

- Now, we have versions 2.4 everywhere (thanks Eric)

- Liang Li sent a new patch to the list to fix the update of a migration 
parameter, included.

Please apply, and sorry for the inconvenience.

Later, Juan.


[v1]
This patch series got:

- migration compression patches by Liang Li
  I have to modify ""type" to "struct" in qapi
- division by zero fixed by Michael Champan.

Thanks, please apply.


The following changes since commit 38003aee196a96edccd4d64471beb1b67e9b2b17:

  Merge remote-tracking branch 'remotes/rth/tags/tcg-next-20150505' into 
staging (2015-05-06 11:16:35 +0100)

are available in the git repository at:

  git://github.com/juanquintela/qemu.git tags/migration/20150507

for you to fetch changes up to 9a43a8e9560629dd788c311c5cae072333f2e7f4:

  migration: Fix migration state update issue (2015-05-07 13:41:47 +0200)

----
migration/next for 20150507


Liang Li (15):
  docs: Add a doc about multiple thread compression
  migration: Add the framework of multi-thread compression
  migration: Add the framework of multi-thread decompression
  qemu-file: Add compression functions to QEMUFile
  arch_init: Alloc and free data struct for compression
  arch_init: Add and free data struct for decompression
  migration: Split save_zero_page from ram_save_page
  migration: Add the core code of multi-thread compression
  migration: Make compression co-work with xbzrle
  migration: Add the core code for decompression
  migration: Add interface to control compression
  migration: Use an array instead of 3 parameters
  migration: Add qmp commands to set and query parameters
  migration: Add hmp interface to set and query parameters
  migration: Fix migration state update issue

Michael Chapman (1):
  migration: avoid divide by zero in xbzrle cache miss rate

 arch_init.c   | 516 --
 docs/multi-thread-compression.txt | 149 +++
 hmp-commands.hx   |  17 ++
 hmp.c |  65 +
 hmp.h |   4 +
 include/migration/migration.h |  10 +
 include/migration/qemu-file.h |   3 +
 migration/migration.c | 122 +
 migration/qemu-file.c |  39 +++
 monitor.c |  25 ++
 qapi-schema.json  |  79 +-
 qmp-commands.hx   |  57 +
 12 files changed, 1059 insertions(+), 27 deletions(-)
 create mode 100644 docs/multi-thread-compression.txt



[Qemu-devel] [PULL 08/16] migration: Add the core code of multi-thread compression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Implement the core logic of the multiple thread compression. At this
point, multiple thread compression can't co-work with xbzrle yet.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 184 +---
 1 file changed, 177 insertions(+), 7 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 48cae22..9f63c0f 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -355,12 +355,33 @@ static DecompressParam *decomp_param;
 static QemuThread *decompress_threads;
 static uint8_t *compressed_data_buf;

+static int do_compress_ram_page(CompressParam *param);
+
 static void *do_data_compress(void *opaque)
 {
-while (!quit_comp_thread) {
+CompressParam *param = opaque;

-/* To be done */
+while (!quit_comp_thread) {
+qemu_mutex_lock(¶m->mutex);
+/* Re-check the quit_comp_thread in case of
+ * terminate_compression_threads is called just before
+ * qemu_mutex_lock(¶m->mutex) and after
+ * while(!quit_comp_thread), re-check it here can make
+ * sure the compression thread terminate as expected.
+ */
+while (!param->start && !quit_comp_thread) {
+qemu_cond_wait(¶m->cond, ¶m->mutex);
+}
+if (!quit_comp_thread) {
+do_compress_ram_page(param);
+}
+param->start = false;
+qemu_mutex_unlock(¶m->mutex);

+qemu_mutex_lock(comp_done_lock);
+param->done = true;
+qemu_cond_signal(comp_done_cond);
+qemu_mutex_unlock(comp_done_lock);
 }

 return NULL;
@@ -368,9 +389,15 @@ static void *do_data_compress(void *opaque)

 static inline void terminate_compression_threads(void)
 {
-quit_comp_thread = true;
+int idx, thread_count;

-/* To be done */
+thread_count = migrate_compress_threads();
+quit_comp_thread = true;
+for (idx = 0; idx < thread_count; idx++) {
+qemu_mutex_lock(&comp_param[idx].mutex);
+qemu_cond_signal(&comp_param[idx].cond);
+qemu_mutex_unlock(&comp_param[idx].mutex);
+}
 }

 void migrate_compress_threads_join(void)
@@ -420,6 +447,7 @@ void migrate_compress_threads_create(void)
  * it's ops to empty.
  */
 comp_param[i].file = qemu_fopen_ops(NULL, &empty_ops);
+comp_param[i].done = true;
 qemu_mutex_init(&comp_param[i].mutex);
 qemu_cond_init(&comp_param[i].cond);
 qemu_thread_create(compress_threads + i, "compress",
@@ -829,6 +857,97 @@ static int ram_save_page(QEMUFile *f, RAMBlock* block, 
ram_addr_t offset,
 return pages;
 }

+static int do_compress_ram_page(CompressParam *param)
+{
+int bytes_sent, blen;
+uint8_t *p;
+RAMBlock *block = param->block;
+ram_addr_t offset = param->offset;
+
+p = memory_region_get_ram_ptr(block->mr) + (offset & TARGET_PAGE_MASK);
+
+bytes_sent = save_page_header(param->file, block, offset |
+  RAM_SAVE_FLAG_COMPRESS_PAGE);
+blen = qemu_put_compression_data(param->file, p, TARGET_PAGE_SIZE,
+ migrate_compress_level());
+bytes_sent += blen;
+atomic_inc(&acct_info.norm_pages);
+
+return bytes_sent;
+}
+
+static inline void start_compression(CompressParam *param)
+{
+param->done = false;
+qemu_mutex_lock(¶m->mutex);
+param->start = true;
+qemu_cond_signal(¶m->cond);
+qemu_mutex_unlock(¶m->mutex);
+}
+
+
+static uint64_t bytes_transferred;
+
+static void flush_compressed_data(QEMUFile *f)
+{
+int idx, len, thread_count;
+
+if (!migrate_use_compression()) {
+return;
+}
+thread_count = migrate_compress_threads();
+for (idx = 0; idx < thread_count; idx++) {
+if (!comp_param[idx].done) {
+qemu_mutex_lock(comp_done_lock);
+while (!comp_param[idx].done && !quit_comp_thread) {
+qemu_cond_wait(comp_done_cond, comp_done_lock);
+}
+qemu_mutex_unlock(comp_done_lock);
+}
+if (!quit_comp_thread) {
+len = qemu_put_qemu_file(f, comp_param[idx].file);
+bytes_transferred += len;
+}
+}
+}
+
+static inline void set_compress_params(CompressParam *param, RAMBlock *block,
+   ram_addr_t offset)
+{
+param->block = block;
+param->offset = offset;
+}
+
+static int compress_page_with_multi_thread(QEMUFile *f, RAMBlock *block,
+   ram_addr_t offset,
+   uint64_t *bytes_transferred)
+{
+int idx, thread_count, bytes_xmit = -1, pages = -1;
+
+thread_count = migrate_compress_threads();
+qemu_mutex_lock(comp_done_lock);
+while (true) {
+for (idx = 0; idx < thread_count; idx++) {
+if (comp_param[idx].done) {
+bytes_xmit = qemu_put_qemu_file(f, comp_param[idx].file);
+

[Qemu-devel] [PULL 11/16] migration: Add interface to control compression

2015-05-07 Thread Juan Quintela
From: Liang Li 

The multiple compression threads can be turned on/off through
qmp and hmp interface before doing live migration.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Reviewed-by: Eric Blake 
Signed-off-by: Juan Quintela 
---
 migration/migration.c |  7 +--
 qapi-schema.json  | 11 ++-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 19409e6..dc7db87 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -611,8 +611,11 @@ bool migrate_zero_blocks(void)

 bool migrate_use_compression(void)
 {
-/* Disable compression before the patch series are applied */
-return false;
+MigrationState *s;
+
+s = migrate_get_current();
+
+return s->enabled_capabilities[MIGRATION_CAPABILITY_COMPRESS];
 }

 int migrate_compress_level(void)
diff --git a/qapi-schema.json b/qapi-schema.json
index 27ec988..83f0b4a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -515,13 +515,22 @@
 #  to enable the capability on the source VM. The feature is disabled 
by
 #  default. (since 1.6)
 #
+# @compress: Use multiple compression threads to accelerate live migration.
+#  This feature can help to reduce the migration traffic, by sending
+#  compressed pages. Please note that if compress and xbzrle are both
+#  on, compress only takes effect in the ram bulk stage, after that,
+#  it will be disabled and only xbzrle takes effect, this can help to
+#  minimize migration traffic. The feature is disabled by default.
+#  (since 2.4 )
+#
 # @auto-converge: If enabled, QEMU will automatically throttle down the guest
 #  to speed up convergence of RAM migration. (since 1.6)
 #
 # Since: 1.2
 ##
 { 'enum': 'MigrationCapability',
-  'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks'] }
+  'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
+   'compress'] }

 ##
 # @MigrationCapabilityStatus
-- 
2.4.0




[Qemu-devel] [PULL 04/16] qemu-file: Add compression functions to QEMUFile

2015-05-07 Thread Juan Quintela
From: Liang Li 

qemu_put_compression_data() compress the data and put it to QEMUFile.
qemu_put_qemu_file() put the data in the buffer of source QEMUFile to
destination QEMUFile.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 include/migration/qemu-file.h |  3 +++
 migration/qemu-file.c | 39 +++
 2 files changed, 42 insertions(+)

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index 745a850..a01c5b8 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -159,6 +159,9 @@ void qemu_put_be32(QEMUFile *f, unsigned int v);
 void qemu_put_be64(QEMUFile *f, uint64_t v);
 int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset);
 int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
+ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
+  int level);
+int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src);
 /*
  * Note that you can only peek continuous bytes from where the current pointer
  * is; you aren't guaranteed to be able to peak to +n bytes unless you've
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 1a4f986..2750365 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -21,6 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include 
 #include "qemu-common.h"
 #include "qemu/iov.h"
 #include "qemu/sockets.h"
@@ -546,3 +547,41 @@ uint64_t qemu_get_be64(QEMUFile *f)
 v |= qemu_get_be32(f);
 return v;
 }
+
+/* compress size bytes of data start at p with specific compression
+ * level and store the compressed data to the buffer of f.
+ */
+
+ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
+  int level)
+{
+ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t);
+
+if (blen < compressBound(size)) {
+return 0;
+}
+if (compress2(f->buf + f->buf_index + sizeof(int32_t), (uLongf *)&blen,
+  (Bytef *)p, size, level) != Z_OK) {
+error_report("Compress Failed!");
+return 0;
+}
+qemu_put_be32(f, blen);
+f->buf_index += blen;
+return blen + sizeof(int32_t);
+}
+
+/* Put the data in the buffer of f_src to the buffer of f_des, and
+ * then reset the buf_index of f_src to 0.
+ */
+
+int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src)
+{
+int len = 0;
+
+if (f_src->buf_index > 0) {
+len = f_src->buf_index;
+qemu_put_buffer(f_des, f_src->buf, f_src->buf_index);
+f_src->buf_index = 0;
+}
+return len;
+}
-- 
2.4.0




[Qemu-devel] [PULL 13/16] migration: Add qmp commands to set and query parameters

2015-05-07 Thread Juan Quintela
From: Liang Li 

Add the qmp commands to tune and query the parameters used in live
migration.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Signed-off-by: Juan Quintela 
---
 migration/migration.c | 56 ++
 qapi-schema.json  | 45 
 qmp-commands.hx   | 57 +++
 3 files changed, 158 insertions(+)

diff --git a/migration/migration.c b/migration/migration.c
index 533717c..732d229 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -188,6 +188,21 @@ MigrationCapabilityStatusList 
*qmp_query_migrate_capabilities(Error **errp)
 return head;
 }

+MigrationParameters *qmp_query_migrate_parameters(Error **errp)
+{
+MigrationParameters *params;
+MigrationState *s = migrate_get_current();
+
+params = g_malloc0(sizeof(*params));
+params->compress_level = s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL];
+params->compress_threads =
+s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
+params->decompress_threads =
+s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
+
+return params;
+}
+
 static void get_xbzrle_cache_stats(MigrationInfo *info)
 {
 if (migrate_use_xbzrle()) {
@@ -301,6 +316,47 @@ void 
qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
 }
 }

+void qmp_migrate_set_parameters(bool has_compress_level,
+int64_t compress_level,
+bool has_compress_threads,
+int64_t compress_threads,
+bool has_decompress_threads,
+int64_t decompress_threads, Error **errp)
+{
+MigrationState *s = migrate_get_current();
+
+if (has_compress_level && (compress_level < 0 || compress_level > 9)) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",
+  "is invalid, it should be in the range of 0 to 9");
+return;
+}
+if (has_compress_threads &&
+(compress_threads < 1 || compress_threads > 255)) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  "compress_threads",
+  "is invalid, it should be in the range of 1 to 255");
+return;
+}
+if (has_decompress_threads &&
+(decompress_threads < 1 || decompress_threads > 255)) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  "decompress_threads",
+  "is invalid, it should be in the range of 1 to 255");
+return;
+}
+
+if (has_compress_level) {
+s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] = compress_level;
+}
+if (has_compress_threads) {
+s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] = compress_threads;
+}
+if (has_decompress_threads) {
+s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
+decompress_threads;
+}
+}
+
 /* shared migration helpers */

 static void migrate_set_state(MigrationState *s, int old_state, int new_state)
diff --git a/qapi-schema.json b/qapi-schema.json
index 9c03e17..9c92482 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -592,6 +592,51 @@
 { 'enum': 'MigrationParameter',
   'data': ['compress-level', 'compress-threads', 'decompress-threads'] }

+#
+# @migrate-set-parameters
+#
+# Set the following migration parameters
+#
+# @compress-level: compression level
+#
+# @compress-threads: compression thread count
+#
+# @decompress-threads: decompression thread count
+#
+# Since: 2.4
+##
+{ 'command': 'migrate-set-parameters',
+  'data': { '*compress-level': 'int',
+'*compress-threads': 'int',
+'*decompress-threads': 'int'} }
+
+#
+# @MigrationParameters
+#
+# @compress-level: compression level
+#
+# @compress-threads: compression thread count
+#
+# @decompress-threads: decompression thread count
+#
+# Since: 2.4
+##
+{ 'struct': 'MigrationParameters',
+  'data': { 'compress-level': 'int',
+'compress-threads': 'int',
+'decompress-threads': 'int'} }
+##
+# @query-migrate-parameters
+#
+# Returns information about the current migration parameters
+#
+# Returns: @MigrationParameters
+#
+# Since: 2.4
+##
+{ 'command': 'query-migrate-parameters',
+  'returns': 'MigrationParameters' }
+
 ##
 # @MouseInfo:
 #
diff --git a/qmp-commands.hx b/qmp-commands.hx
index d4a837c..7506774 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3443,6 +3443,63 @@ EQMP
 },

 SQMP
+migrate-set-parameters
+--
+
+Set migration parameters
+
+- "compress-level": set compression level during migration (json-int)
+- "compress-threads": set compression thread count for migration (json-int)
+- "decompress-threads": set decompression thread count for migration (json-int)
+
+Arguments:
+
+Example:
+
+-> { "execute": "migrat

[Qemu-devel] [PULL 10/16] migration: Add the core code for decompression

2015-05-07 Thread Juan Quintela
From: Liang Li 

Implement the core logic of multiple thread decompression,
the decompression can work now.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 50 --
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index b81acc9..9b161f9 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -888,6 +888,13 @@ static inline void start_compression(CompressParam *param)
 qemu_mutex_unlock(¶m->mutex);
 }

+static inline void start_decompression(DecompressParam *param)
+{
+qemu_mutex_lock(¶m->mutex);
+param->start = true;
+qemu_cond_signal(¶m->cond);
+qemu_mutex_unlock(¶m->mutex);
+}

 static uint64_t bytes_transferred;

@@ -1459,8 +1466,26 @@ void ram_handle_compressed(void *host, uint8_t ch, 
uint64_t size)

 static void *do_data_decompress(void *opaque)
 {
+DecompressParam *param = opaque;
+unsigned long pagesize;
+
 while (!quit_decomp_thread) {
-/* To be done */
+qemu_mutex_lock(¶m->mutex);
+while (!param->start && !quit_decomp_thread) {
+qemu_cond_wait(¶m->cond, ¶m->mutex);
+pagesize = TARGET_PAGE_SIZE;
+if (!quit_decomp_thread) {
+/* uncompress() will return failed in some case, especially
+ * when the page is dirted when doing the compression, it's
+ * not a problem because the dirty page will be retransferred
+ * and uncompress() won't break the data in other pages.
+ */
+uncompress((Bytef *)param->des, &pagesize,
+   (const Bytef *)param->compbuf, param->len);
+}
+param->start = false;
+}
+qemu_mutex_unlock(¶m->mutex);
 }

 return NULL;
@@ -1492,6 +1517,11 @@ void migrate_decompress_threads_join(void)
 quit_decomp_thread = true;
 thread_count = migrate_decompress_threads();
 for (i = 0; i < thread_count; i++) {
+qemu_mutex_lock(&decomp_param[i].mutex);
+qemu_cond_signal(&decomp_param[i].cond);
+qemu_mutex_unlock(&decomp_param[i].mutex);
+}
+for (i = 0; i < thread_count; i++) {
 qemu_thread_join(decompress_threads + i);
 qemu_mutex_destroy(&decomp_param[i].mutex);
 qemu_cond_destroy(&decomp_param[i].cond);
@@ -1508,7 +1538,23 @@ void migrate_decompress_threads_join(void)
 static void decompress_data_with_multi_threads(uint8_t *compbuf,
void *host, int len)
 {
-/* To be done */
+int idx, thread_count;
+
+thread_count = migrate_decompress_threads();
+while (true) {
+for (idx = 0; idx < thread_count; idx++) {
+if (!decomp_param[idx].start) {
+memcpy(decomp_param[idx].compbuf, compbuf, len);
+decomp_param[idx].des = host;
+decomp_param[idx].len = len;
+start_decompression(&decomp_param[idx]);
+break;
+}
+}
+if (idx < thread_count) {
+break;
+}
+}
 }

 static int ram_load(QEMUFile *f, void *opaque, int version_id)
-- 
2.4.0




[Qemu-devel] [PATCH v2 0/2] semihosting: clean up and add --semihosting-config arg

2015-05-07 Thread Leon Alrae
Hi,

This patch series adds "arg=" sub-option to --semihosting-config group. It
allows building up a list of input arguments as it can appear multiple
times in the command line. This is a flexible solution for creating
argc/argv for the guest program (needed by UHI semihosting for example).
RFC patch and related discussion was here:
https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg00115.html

It also contains some generic code clean up -- all semihosting related
things were moved to vl.c (where they are actually set) and grouped in
the SemihostingConfig structure. They can be accessed via
include/exec/semihost.h introduced in this patch series.

Since this touches generic semihosting code I'm sending it as a separate
patchset from MIPS-specific UHI semihosting patches.

Regards,
Leon

v2:
* squash clean-up related patches so renaming is not required (these
  modifications are relatively simple anyway).

Leon Alrae (2):
  semihosting: create SemihostingConfig structure and semihost.h
  semihosting: add --semihosting-config arg sub-argument

 gdbstub.c |  8 +++---
 include/exec/gdbstub.h|  6 
 include/exec/semihost.h   | 56 +
 include/sysemu/sysemu.h   |  1 -
 qemu-options.hx   |  8 --
 target-arm/helper.c   |  7 +++--
 target-lm32/helper.c  |  3 +-
 target-m68k/op_helper.c   |  5 ++--
 target-xtensa/translate.c |  3 +-
 vl.c  | 71 +--
 10 files changed, 137 insertions(+), 31 deletions(-)
 create mode 100644 include/exec/semihost.h




[Qemu-devel] [PULL 07/16] migration: Split save_zero_page from ram_save_page

2015-05-07 Thread Juan Quintela
From: Liang Li 

Split the function save_zero_page from ram_save_page so that we can
reuse it later.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 61 +++--
 1 file changed, 43 insertions(+), 18 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index ebd246f..48cae22 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -716,6 +716,34 @@ static void migration_bitmap_sync(void)
 }

 /**
+ * save_zero_page: Send the zero page to the stream
+ *
+ * Returns: Number of pages written.
+ *
+ * @f: QEMUFile where to send the data
+ * @block: block that contains the page we want to send
+ * @offset: offset inside the block for the page
+ * @p: pointer to the page
+ * @bytes_transferred: increase it with the number of transferred bytes
+ */
+static int save_zero_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
+  uint8_t *p, uint64_t *bytes_transferred)
+{
+int pages = -1;
+
+if (is_zero_range(p, TARGET_PAGE_SIZE)) {
+acct_info.dup_pages++;
+*bytes_transferred += save_page_header(f, block,
+   offset | 
RAM_SAVE_FLAG_COMPRESS);
+qemu_put_byte(f, 0);
+*bytes_transferred += 1;
+pages = 1;
+}
+
+return pages;
+}
+
+/**
  * ram_save_page: Send the given page to the stream
  *
  * Returns: Number of pages written.
@@ -763,25 +791,22 @@ static int ram_save_page(QEMUFile *f, RAMBlock* block, 
ram_addr_t offset,
 acct_info.dup_pages++;
 }
 }
-} else if (is_zero_range(p, TARGET_PAGE_SIZE)) {
-acct_info.dup_pages++;
-*bytes_transferred += save_page_header(f, block,
-   offset | 
RAM_SAVE_FLAG_COMPRESS);
-qemu_put_byte(f, 0);
-*bytes_transferred += 1;
-pages = 1;
-/* Must let xbzrle know, otherwise a previous (now 0'd) cached
- * page would be stale
- */
-xbzrle_cache_zero_page(current_addr);
-} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
-pages = save_xbzrle_page(f, &p, current_addr, block,
- offset, last_stage, bytes_transferred);
-if (!last_stage) {
-/* Can't send this cached data async, since the cache page
- * might get updated before it gets to the wire
+} else {
+pages = save_zero_page(f, block, offset, p, bytes_transferred);
+if (pages > 0) {
+/* Must let xbzrle know, otherwise a previous (now 0'd) cached
+ * page would be stale
  */
-send_async = false;
+xbzrle_cache_zero_page(current_addr);
+} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
+pages = save_xbzrle_page(f, &p, current_addr, block,
+ offset, last_stage, bytes_transferred);
+if (!last_stage) {
+/* Can't send this cached data async, since the cache page
+ * might get updated before it gets to the wire
+ */
+send_async = false;
+}
 }
 }

-- 
2.4.0




[Qemu-devel] [PULL 09/16] migration: Make compression co-work with xbzrle

2015-05-07 Thread Juan Quintela
From: Liang Li 

Now, multiple thread compression can co-work with xbzrle. when
xbzrle is on, multiple thread compression will only work at the
first round of RAM data sync.

Signed-off-by: Liang Li 
Signed-off-by: Yang Zhang 
Reviewed-by: Dr.David Alan Gilbert 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch_init.c b/arch_init.c
index 9f63c0f..b81acc9 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -349,6 +349,8 @@ static QemuMutex *comp_done_lock;
 static QemuCond *comp_done_cond;
 /* The empty QEMUFileOps will be used by file in CompressParam */
 static const QEMUFileOps empty_ops = { };
+
+static bool compression_switch;
 static bool quit_comp_thread;
 static bool quit_decomp_thread;
 static DecompressParam *decomp_param;
@@ -435,6 +437,7 @@ void migrate_compress_threads_create(void)
 return;
 }
 quit_comp_thread = false;
+compression_switch = true;
 thread_count = migrate_compress_threads();
 compress_threads = g_new0(QemuThread, thread_count);
 comp_param = g_new0(CompressParam, thread_count);
@@ -1060,9 +1063,16 @@ static int ram_find_and_save_block(QEMUFile *f, bool 
last_stage,
 block = QLIST_FIRST_RCU(&ram_list.blocks);
 complete_round = true;
 ram_bulk_stage = false;
+if (migrate_use_xbzrle()) {
+/* If xbzrle is on, stop using the data compression at this
+ * point. In theory, xbzrle can do better than compression.
+ */
+flush_compressed_data(f);
+compression_switch = false;
+}
 }
 } else {
-if (migrate_use_compression()) {
+if (compression_switch && migrate_use_compression()) {
 pages = ram_save_compressed_page(f, block, offset, last_stage,
  bytes_transferred);
 } else {
-- 
2.4.0




  1   2   3   >