Re: [Qemu-devel] [PATCH v2 3/3] hostmem-file: make option 'size' optional

2016-10-27 Thread Haozhong Zhang

On 10/28/16 10:06 +0800, Haozhong Zhang wrote:

On 10/27/16 12:55 -0200, Eduardo Habkost wrote:

On Thu, Oct 27, 2016 at 12:23:00PM +0800, Haozhong Zhang wrote:

[..]

static char *get_mem_path(Object *o, Error **errp)
diff --git a/exec.c b/exec.c
index 264a25f..89065bd 100644
--- a/exec.c
+++ b/exec.c
@@ -1234,7 +1234,7 @@ static int64_t get_file_size(int fd)
}

static void *file_ram_alloc(RAMBlock *block,
-ram_addr_t memory,
+ram_addr_t *memory,
const char *path,
Error **errp)
{
@@ -1245,6 +1245,7 @@ static void *file_ram_alloc(RAMBlock *block,
void *area = MAP_FAILED;
int fd = -1;
int64_t file_size;
+ram_addr_t mem_size = *memory;

if (kvm_enabled() && !kvm_has_sync_mmu()) {
error_setg(errp,
@@ -1309,21 +1310,27 @@ static void *file_ram_alloc(RAMBlock *block,

file_size = get_file_size(fd);

-if (memory < block->page_size) {
+if (!mem_size && file_size > 0) {
+mem_size = file_size;


Maybe we should set *memory here and not below?



Qemu currently sets the memory region size to the file size, and block
length to the aligned file size, so the code here can be changed as below:

  memory_region_set_size(block->mr, mem_size);
  mem_size = HOST_PAGE_ALIGN(mem_size);
  *memory = mem_size;

The second line is necessary because Qemu currently passes the aligned
file size to file_ram_alloc().



I meant that QEMU currently sets the memory region size of the 'size'
option and the block length to the aligned 'size' option. If the file
size is used when 'size' option is not specified, QEMU should do the
same thing.

Haozhong


+memory_region_set_size(block->mr, mem_size);


This could be simplified (and made safer) if the memory region
got initialized by memory_region_init_ram_from_file() after we
already mapped/allocated the file (so we avoid surprises in case
other code does something weird because of the temporarily
zero-sized MemoryRegion). But it would probably be an intrusive
change, so I guess changing the memory size here is OK. Paolo,
what do you think?



I will add a check to ensure that the size of block->mr is either 0 or
mem_size, and only set the region size in the former case. The former
corresponds to the case that 'size' option is not given or 0. The
latter corresponds to the case that 'size' option is given.


+}
+
+if (mem_size < block->page_size) {
error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
   "or larger than page size 0x%zx",
-   memory, block->page_size);
+   mem_size, block->page_size);
goto error;
}

-if (file_size > 0 && file_size < memory) {
+if (file_size > 0 && file_size < mem_size) {
error_setg(errp, "backing store %s size %"PRId64
   " does not match 'size' option %"PRIu64,
-   path, file_size, memory);
+   path, file_size, mem_size);
goto error;
}

-memory = ROUND_UP(memory, block->page_size);
+mem_size = ROUND_UP(mem_size, block->page_size);
+*memory = mem_size;


Why exactly did you choose to set *memory to the rounded-up size
and not file_size? Changing *memory to the rounded-up value would
be additional behavior that is not described in the commit
message. I believe we should change *memory only if *memory == 0,
and avoid touching it otherwise.



Setting *memory here is buggy. I'll move it as above.

Thanks,
Haozhong


[..]



[Qemu-devel] [PATCH v13 0/2] virtio-crypto: virtio crypto device specification

2016-10-27 Thread Gonglei
This is the specification about a new virtio crypto device.

You can get the source code from the below website:

[PATCH v3 00/10] virtio-crypto: introduce framework and device emulation
  https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg04132.html

[PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
 https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg07327.html

[PATCH v5 00/14] virtio-crypto: introduce framework and device emulation
 https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg00963.html

 ...

[PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
 https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04755.html

For more information, please see:
 http://qemu-project.org/Features/VirtioCrypto

Please help to review, thanks.

CC: Michael S. Tsirkin 
CC: Cornelia Huck 
CC: Stefan Hajnoczi 
CC: Lingli Deng 
CC: Jani Kokkonen 
CC: Ola Liljedahl 
CC: Varun Sethi 
CC: Zeng Xin 
CC: Keating Brian 
CC: Ma Liang J 
CC: Griffin John 
CC: Hanweidong 
CC: Mihai Claudiu Caraman 

Changes since v12:
 - add max_size field in the virtio-crypto device config in order
   to tell the driver what's maximum size of crypto request the
   device supports. [Michael]
 - add max_cipher_key_len and max_auth_key_len in the device config
   too for the symmetric algorithms to limit resource utilization by
   guest. [Thoughts come from Michael]

Changes since v11:
 - drop scatter-gather I/O definition for virtio crypto device because
   The vring already provides scatter-gather I/O.  It is usually not
   necessary to define scatter-gather I/O at the device level.  [Stefan]
 - perfect algorithm chain parameters' definition.
 - add HASH/MAC parameter structure.

Changes since v10:
 - fix typos s/filed/field/. [Xin]
 - replace 'real cypto accelerator' with 'backend crypto accelerator'. [mst]
 - drop KDF, ASYM, PRIMITIVE services description temporarily. [mst]
 - write a device requirement are testable about VIRTIO_CRYPTO_S_HW_READY. [mst]
 - add a space before * in one code comment. [mst]
 - reset the layout of all crypto operations for better asymmetric algos 
support. [Xin]
 - add more detailed description for initialization vector under different 
modes.
 - sed -i 's/VIRTIO_CRYPTO_OP_/VIRTIO_CRYPTO_/g' for general usage in asym 
algos. [Xin]

Changes since v9:
 - request a native speaker go over the text and fix corresponding grammar 
issues. [mst]
 - make some description more appropriated over here and there. [mst]
 - rewrite some requirement for both device and driver. [mst]
 - use RFC 2119 keywords. [mst]
 - fix some complaints by Xelatex and typoes. [Xin Zeng]
 - add scatter/getter chain support for possible large block data.

Thanks for your review, Michael and Xin.

Changes from v8:
 - add additional auth gpa and length to struct virtio_crypto_sym_data_req;
 - add definition of op in struct virtio_crypto_cipher_session_para,
  VIRTIO_CRYPTO_OP_ENCRYPT and VIRTIO_CRYPTO_OP_DECRYPT;
 - make all structures 64bit aligned in order to support different
  architectures more conveniently [Alex & Stefan]
 - change to devicenormative{\subsection} and \drivernormative{\subsection} in 
some sections [Stefan]
 - driver does not have to initialize all data virtqueues if it wants to use 
fewer [Stefan]
 - drop VIRTIO_CRYPTO_NO_SERVICE definition [Stefan]
 - many grammatical problems and typos. [Stefan]
 - rename VIRTIO_CRYPTO_MAC_CMAC_KASUMI_F9 to VIRTIO_CRYPTO_MAC_CMAC_KASUMI_F9,
  and VIRTIO_CRYPTO_MAC_CMAC_SNOW3G_UIA2 to VIRTIO_CRYPTO_MAC_SNOW3G_UIA2. 
[Liang Ma]
 - drop queue_id property of struct virtio_crypto_op_data_req.
 - reconstruct some structures about session operation request.
 - introduce struct virtio_crypto_alg_chain_session_req and struct 
virtio_crypto_alg_chain_data_req,
  introduce chain para, output, input structures as well.
 - change some sections' layout for better compatibility, for asymmetric algos. 
[Xin Zeng]

Changes from v7:
 - fix some grammar or typo problems.
 - add more detailed description at steps of encryption section.

Changes from v6:
 - drop verion filed in struct virtio_crypto_config. [Michael & Cornelia]
 - change the incorrect description in initialization routine. [Zeng Xin]
 - redefine flag u16 to make structure alignment. [Zeng Xin]
 - move the content of virtio_crypto_hash_session_para into
   virtio_crypto_hash_session_input directly, Same to MAC/SYM/AEAD session 
creation. [Zeng Xin]
 - adjuest the sequence of idata and odata refer to the virtio scsi parts,
   meanwhile add the comments of device-readable/writable for them.
 - add restrictive documents for the guest memory in some structure, which
   MUST be 

[Qemu-devel] [PATCH v13 1/2] virtio-crypto: Add virtio crypto device specification

2016-10-27 Thread Gonglei
The virtio crypto device is a virtual crypto device (ie. hardware
crypto accelerator card). Currently, the virtio crypto device provides
the following crypto services: CIPHER, MAC, HASH, and AEAD.

In this patch, CIPHER, MAC, HASH, AEAD services are introduced.

VIRTIO-153

Signed-off-by: Gonglei 
CC: Michael S. Tsirkin 
CC: Cornelia Huck 
CC: Stefan Hajnoczi 
CC: Lingli Deng 
CC: Jani Kokkonen 
CC: Ola Liljedahl 
CC: Varun Sethi 
CC: Zeng Xin 
CC: Keating Brian 
CC: Ma Liang J 
CC: Griffin John 
CC: Hanweidong 
CC: Mihai Claudiu Caraman 
---
 content.tex   |2 +
 virtio-crypto.tex | 1009 +
 2 files changed, 1011 insertions(+)
 create mode 100644 virtio-crypto.tex

diff --git a/content.tex b/content.tex
index 4b45678..ab75f78 100644
--- a/content.tex
+++ b/content.tex
@@ -5750,6 +5750,8 @@ descriptor for the \field{sense_len}, \field{residual},
 \field{status_qualifier}, \field{status}, \field{response} and
 \field{sense} fields.
 
+\input{virtio-crypto.tex}
+
 \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
 
 Currently there are three device-independent feature bits defined:
diff --git a/virtio-crypto.tex b/virtio-crypto.tex
new file mode 100644
index 000..448296e
--- /dev/null
+++ b/virtio-crypto.tex
@@ -0,0 +1,1009 @@
+\section{Crypto Device}\label{sec:Device Types / Crypto Device}
+
+The virtio crypto device is a virtual cryptography device as well as a kind of
+virtual hardware accelerator for virtual machines. The encryption and
+decryption requests are placed in the data queue and are ultimately handled by 
the
+backend crypto accelerators. The second queue is the control queue used to 
create 
+or destroy sessions for symmetric algorithms and will control some advanced
+features in the future. The virtio crypto device provides the following crypto
+services: CIPHER, MAC, HASH, and AEAD.
+
+
+\subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}
+
+20
+
+\subsection{Virtqueues}\label{sec:Device Types / Crypto Device / Virtqueues}
+
+\begin{description}
+\item[0] dataq1
+\item[\ldots]
+\item[N-1] dataqN
+\item[N] controlq
+\end{description}
+
+N is set by \field{max_dataqueues}.
+
+\subsection{Feature bits}\label{sec:Device Types / Crypto Device / Feature 
bits}
+
+Undefined currently.
+
+\subsection{Device configuration layout}\label{sec:Device Types / Crypto 
Device / Device configuration layout}
+
+The following driver-read-only configuration fields are defined:
+
+\begin{lstlisting}
+struct virtio_crypto_config {
+le32 status;
+le32 max_dataqueues;
+le32 crypto_services;
+/* Detailed algorithms mask */
+le32 cipher_algo_l;
+le32 cipher_algo_h;
+le32 hash_algo;
+le32 mac_algo_l;
+le32 mac_algo_h;
+le32 aead_algo;
+/* Maximum length of cipher key */
+le32 max_cipher_key_len;
+/* Maximum length of authenticated key */
+le32 max_auth_key_len;
+le32 reserve;
+/* Maximum size of each crypto request's content */
+le64 max_size;
+};
+\end{lstlisting}
+
+The value of the \field{status} field is VIRTIO_CRYPTO_S_HW_READY or 
VIRTIO_CRYPTO_S_STARTED.
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
+#define VIRTIO_CRYPTO_S_STARTED  (1 << 1)
+\end{lstlisting}
+
+The following driver-read-only fields include \field{max_dataqueues}, which 
specifies the
+maximum number of data virtqueues (dataq1\ldots dataqN), and 
\field{crypto_services},
+which indicates the crypto services the virtio crypto supports.
+
+The following services are defined:
+
+\begin{lstlisting}
+/* CIPHER service */
+#define VIRTIO_CRYPTO_SERVICE_CIPHER (0)
+/* HASH service */
+#define VIRTIO_CRYPTO_SERVICE_HASH   (1)
+/* MAC (Message Authentication Codes) service */
+#define VIRTIO_CRYPTO_SERVICE_MAC(2)
+/* AEAD (Authenticated Encryption with Associated Data) service */
+#define VIRTIO_CRYPTO_SERVICE_AEAD   (3)
+\end{lstlisting}
+
+The last driver-read-only fields specify detailed algorithms masks 
+the device offers for corresponding services. The following CIPHER algorithms
+are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_NO_CIPHER 0
+#define VIRTIO_CRYPTO_CIPHER_ARC4   1
+#define VIRTIO_CRYPTO_CIPHER_AES_ECB2
+#define VIRTIO_CRYPTO_CIPHER_AES_CBC3
+#define VIRTIO_CRYPTO_CIPHER_AES_CTR4
+#define VIRTIO_CRYPTO_CIPHER_DES_ECB5
+#define VIRTIO_CRYPTO_CIPHER_DES_CBC6
+#define VIRTIO_CRYPTO_CIPHER_3DES_ECB   7
+#define VIRTIO_CRYPTO_CIPHER_3DES_CBC   8
+#define VIRTIO_CRYPTO_CIPHER_3DES_CTR   9
+#define 

[Qemu-devel] [PATCH v13 2/2] virtio-crypto: Add conformance clauses

2016-10-27 Thread Gonglei
Add the conformance targets and clauses for
virtio-crypto device.

Signed-off-by: Gonglei 
---
 conformance.tex | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/conformance.tex b/conformance.tex
index f59e360..3bde4b6 100644
--- a/conformance.tex
+++ b/conformance.tex
@@ -146,6 +146,21 @@ An SCSI host driver MUST conform to the following 
normative statements:
 \item \ref{drivernormative:Device Types / SCSI Host Device / Device Operation 
/ Device Operation: eventq}
 \end{itemize}
 
+\subsection{Crypto Driver Conformance}\label{sec:Conformance / Driver 
Conformance / Crypto Driver Conformance}
+
+An Crypto driver MUST conform to the following normative statements:
+
+\begin{itemize}
+\item \ref{drivernormative:Device Types / Crypto Device / Device configuration 
layout}
+\item \ref{drivernormative:Device Types / Crypto Device / Device 
Initialization}
+\item \ref{drivernormative:Device Types / Crypto Device / Device Operation / 
Control Virtqueue / Session operation / Session operation: create session}
+\item \ref{drivernormative:Device Types / Crypto Device / Device Operation / 
Control Virtqueue / Session operation / Session operation: destroy session}
+\item \ref{drivernormative:Device Types / Crypto Device / Device Operation / 
HASH Service operation}
+\item \ref{drivernormative:Device Types / Crypto Device / Device Operation / 
MAC Service operation}
+\item \ref{drivernormative:Device Types / Crypto Device / Device Operation / 
Symmetric algorithms Operation}
+\item \ref{drivernormative:Device Types / Crypto Device / Device Operation / 
AEAD Service operation}
+\end{itemize}
+
 \section{Device Conformance}\label{sec:Conformance / Device Conformance}
 
 A device MUST conform to the following normative statements:
@@ -267,6 +282,21 @@ An SCSI host device MUST conform to the following 
normative statements:
 \item \ref{devicenormative:Device Types / SCSI Host Device / Device Operation 
/ Device Operation: eventq}
 \end{itemize}
 
+\subsection{Crypto Device Conformance}\label{sec:Conformance / Device 
Conformance / Crypto Device Conformance}
+
+An Crypto device MUST conform to the following normative statements:
+
+\begin{itemize}
+\item \ref{devicenormative:Device Types / Crypto Device / Device configuration 
layout}
+\item \ref{devicenormative:Device Types / Crypto Device / Device 
Initialization}
+\item \ref{devicenormative:Device Types / Crypto Device / Device Operation / 
Control Virtqueue / Session operation / Session operation: create session}
+\item \ref{devicenormative:Device Types / Crypto Device / Device Operation / 
Control Virtqueue / Session operation / Session operation: destroy session}
+\item \ref{devicenormative:Device Types / Crypto Device / Device Operation / 
HASH Service operation}
+\item \ref{devicenormative:Device Types / Crypto Device / Device Operation / 
MAC Service operation}
+\item \ref{devicenormative:Device Types / Crypto Device / Device Operation / 
Symmetric algorithms Operation}
+\item \ref{devicenormative:Device Types / Crypto Device / Device Operation / 
AEAD Service operation}
+\end{itemize}
+
 \section{Legacy Interface: Transitional Device and
 Transitional Driver Conformance}\label{sec:Conformance / Legacy
 Interface: Transitional Device and 
-- 
1.7.12.4





[Qemu-devel] [RFC] powernv: CPU compatibility modes don't make sense for powernv

2016-10-27 Thread David Gibson
powernv has some code (derived from the spapr equivalent) used in device
tree generation which depends on the CPU's compatibility mode / logical
PVR.  However, compatibility modes don't make sense on powernv - at least
not as a property controlled by the host - because the guest in powernv
has full hypervisor level access to the virtual system, and so owns the
PCR (Processor Compatibility Register) which implements compatiblity modes.

Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

Hi Cédric, I'd appreciate it if you can double check my reasoning
here.  This patch gets powernv out of the way of a bunch of
compatibility mode cleanups I have in the works.

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 82276e0..6af3424 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -110,7 +110,7 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore 
*pc, void *fdt)
 CPUState *cs = CPU(DEVICE(pc->threads));
 DeviceClass *dc = DEVICE_GET_CLASS(cs);
 PowerPCCPU *cpu = POWERPC_CPU(cs);
-int smt_threads = ppc_get_compat_smt_threads(cpu);
+int smt_threads = CPU_CORE(pc)->nr_threads;
 CPUPPCState *env = >env;
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
 uint32_t servers_prop[smt_threads];
@@ -206,10 +206,6 @@ static void powernv_create_core_node(PnvChip *chip, 
PnvCore *pc, void *fdt)
 _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
pa_features, sizeof(pa_features;
 
-if (cpu->cpu_version) {
-_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu->cpu_version)));
-}
-
 /* Build interrupt servers properties */
 for (i = 0; i < smt_threads; i++) {
 servers_prop[i] = cpu_to_be32(pc->pir + i);
-- 
2.7.4




Re: [Qemu-devel] [PATCH v9 04/12] vfio iommu: Add support for mediated devices

2016-10-27 Thread Alexey Kardashevskiy
On 27/10/16 23:31, Kirti Wankhede wrote:
> 
> 
> On 10/27/2016 12:50 PM, Alexey Kardashevskiy wrote:
>> On 18/10/16 08:22, Kirti Wankhede wrote:
>>> VFIO IOMMU drivers are designed for the devices which are IOMMU capable.
>>> Mediated device only uses IOMMU APIs, the underlying hardware can be
>>> managed by an IOMMU domain.
>>>
>>> Aim of this change is:
>>> - To use most of the code of TYPE1 IOMMU driver for mediated devices
>>> - To support direct assigned device and mediated device in single module
>>>
>>> Added two new callback functions to struct vfio_iommu_driver_ops. Backend
>>> IOMMU module that supports pining and unpinning pages for mdev devices
>>> should provide these functions.
>>> Added APIs for pining and unpining pages to VFIO module. These calls back
>>> into backend iommu module to actually pin and unpin pages.
>>>
>>> This change adds pin and unpin support for mediated device to TYPE1 IOMMU
>>> backend module. More details:
>>> - When iommu_group of mediated devices is attached, task structure is
>>>   cached which is used later to pin pages and page accounting.
>>
>>
>> For SPAPR TCE IOMMU driver, I ended up caching mm_struct with
>> atomic_inc(>mm->mm_count) (patches are on the way) instead of
>> using @current or task as the process might be gone while VFIO container is
>> still alive and @mm might be needed to do proper cleanup; this might not be
>> an issue with this patchset now but still you seem to only use @mm from
>> task_struct.
>>
> 
> Consider the example of QEMU process which creates VFIO container, QEMU
> in its teardown path would release the container. How could container be
> alive when process is gone?

do_exit() in kernel/exit.c calls exit_mm() (which sets NULL to tsk->mm)
first, and then releases open files by calling  exit_files(). So
container's release() does not have current->mm.



> 
> Kirti
> 
>>
>>
>>> - It keeps track of pinned pages for mediated domain. This data is used to
>>>   verify unpinning request and to unpin remaining pages while detaching, if
>>>   there are any.
>>> - Used existing mechanism for page accounting. If iommu capable domain
>>>   exist in the container then all pages are already pinned and accounted.
>>>   Accouting for mdev device is only done if there is no iommu capable
>>>   domain in the container.
>>> - Page accouting is updated on hot plug and unplug mdev device and pass
>>>   through device.
>>>
>>> Tested by assigning below combinations of devices to a single VM:
>>> - GPU pass through only
>>> - vGPU device only
>>> - One GPU pass through and one vGPU device
>>> - Linux VM hot plug and unplug vGPU device while GPU pass through device
>>>   exist
>>> - Linux VM hot plug and unplug GPU pass through device while vGPU device
>>>   exist
>>>
>>> Signed-off-by: Kirti Wankhede 
>>> Signed-off-by: Neo Jia 
>>> Change-Id: I295d6f0f2e0579b8d9882bfd8fd5a4194b97bd9a
>>
>>


-- 
Alexey



Re: [Qemu-devel] [Bug 1384892] Re: RTL8168 NIC VFIO not working anymore since QEMU 2.1

2016-10-27 Thread Thorsten Kohfeldt
Hi *,

it seems we could finally fix this bug:
https://bugs.launchpad.net/qemu/+bug/1384892

with the following patches:
https://lists.nongnu.org/archive/html/qemu-devel/2016-10/msg07260.html

Regards,

Thorsten

Am 22.06.2016 um 13:10 schrieb T. Huth:
> Alex' patch has been included here:
> http://git.qemu.org/?p=qemu.git;a=commitdiff;h=69970fcef937bddd7f745
> ... so I assume this ticket could be closed now?
>

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

Title:
  RTL8168 NIC VFIO not working anymore since QEMU 2.1

Status in QEMU:
  New

Bug description:
  After upgrading QEMU from 2.0 to 2.1 (and libiscsi from 1.7.0 to 1.12 as a 
dependency) my two RTL8168 NICs stopped working.
  The NICs do not respond to any command and even the LEDs on the network 
connection turn off, a few seconds after the VM started.
  To get them back running I had to downgrade to 2.0 and restart the system.
  Unfortunately, I have no clue what to do or how to debug this problem since 
there are no specific errors logged.
  I tried two different VMs: Debian Wheezy and IPFire (see attachment for 
further details).
  The QEMU 2.1 changelog states "Support for RTL8168 NICs." so there were some 
major changes done, I guess.

  On the IPFire guest the kernel log shows many of these lines:
  r8169 :00:07.0 green1: rtl_eriar_cond == 1 (loop: 100, delay: 100)
  r8169 :00:07.0 green1: rtl_phy_reset_cond == 1 (loop: 100, delay: 1)

  On the Debian guest there is only:
  r8169 :00:07.0: firmware: agent loaded rtl_nic/rtl8168e-3.fw into memory
  r8169 :00:07.0: lan0: link down
  ADDRCONF(NETDEV_UP): lan0: link is not ready

  The commandline for IPFire can be seen in the attachment. It is the same for 
Debian.
  There are also the complete kernel logs for the working (2.0) and non-working 
(2.1) cases.

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



Re: [Qemu-devel] [PATCH COLO-Frame (Base) v23 18/18] MAINTAINERS: Add maintainer for COLO framework related files

2016-10-27 Thread Hailiang Zhang

Hi Amit,

On 2016/10/27 15:34, Amit Shah wrote:

On (Thu) 27 Oct 2016 [14:43:09], zhanghailiang wrote:

Add myself as co-maintainer of COLO framework, so that
I can get CC'ed on future patches and bugs for this feature.

Signed-off-by: zhanghailiang 


Reviewed-by: Amit Shah 



Thank you.

Since there are only two or three days left for
Qemu 2.8's soft feature freeze.

Could you please give a pull request for this series?
I'm sure if Juan has time or not, because we didn't
get any response from him.

Hailiang



Amit

.






Re: [Qemu-devel] [PATCH v2 3/3] hostmem-file: make option 'size' optional

2016-10-27 Thread Haozhong Zhang

On 10/27/16 12:55 -0200, Eduardo Habkost wrote:

On Thu, Oct 27, 2016 at 12:23:00PM +0800, Haozhong Zhang wrote:

If 'size' option is not given, Qemu will use the file size of 'mem-path'
instead. If an empty file, a non-existing file or a directory is specified
by option 'mem-path', a non-zero option 'size' is still needed.

Signed-off-by: Haozhong Zhang 
---
 backends/hostmem-file.c | 28 
 exec.c  | 33 -
 2 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 42efb2f..6ee4352 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -39,17 +39,14 @@ static void
 file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
+Error *local_err = NULL;

-if (!backend->size) {
-error_setg(errp, "can't create backend with size 0");
-return;
-}
 if (!fb->mem_path) {
-error_setg(errp, "mem-path property not set");
-return;
+error_setg(_err, "mem-path property not set");
+goto out;
 }
 #ifndef CONFIG_LINUX
-error_setg(errp, "-mem-path not supported on this host");
+error_setg(_err, "-mem-path not supported on this host");
 #else
 if (!memory_region_size(>mr)) {
 gchar *path;
@@ -58,10 +55,25 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 memory_region_init_ram_from_file(>mr, OBJECT(backend),
  path,
  backend->size, fb->share,
- fb->mem_path, errp);
+ fb->mem_path, _err);
 g_free(path);
+
+if (local_err) {
+goto out;
+}
+
+if (!backend->size) {
+backend->size = memory_region_size(>mr);
+}
 }
 #endif
+
+if (!backend->size) {
+error_setg(_err, "can't create backend with size 0");
+}


You need to move this check before the #endif line, as an error
is already unconditionally set in local_err in the !CONFIG_LINUX
path, and a second error_setg() call would trigger an assert()
inside error_setv().



will change


+
+ out:
+error_propagate(errp, local_err);
 }

 static char *get_mem_path(Object *o, Error **errp)
diff --git a/exec.c b/exec.c
index 264a25f..89065bd 100644
--- a/exec.c
+++ b/exec.c
@@ -1234,7 +1234,7 @@ static int64_t get_file_size(int fd)
 }

 static void *file_ram_alloc(RAMBlock *block,
-ram_addr_t memory,
+ram_addr_t *memory,
 const char *path,
 Error **errp)
 {
@@ -1245,6 +1245,7 @@ static void *file_ram_alloc(RAMBlock *block,
 void *area = MAP_FAILED;
 int fd = -1;
 int64_t file_size;
+ram_addr_t mem_size = *memory;

 if (kvm_enabled() && !kvm_has_sync_mmu()) {
 error_setg(errp,
@@ -1309,21 +1310,27 @@ static void *file_ram_alloc(RAMBlock *block,

 file_size = get_file_size(fd);

-if (memory < block->page_size) {
+if (!mem_size && file_size > 0) {
+mem_size = file_size;


Maybe we should set *memory here and not below?



Qemu currently sets the memory region size to the file size, and block
length to the aligned file size, so the code here can be changed as below:

   memory_region_set_size(block->mr, mem_size);
   mem_size = HOST_PAGE_ALIGN(mem_size);
   *memory = mem_size;

The second line is necessary because Qemu currently passes the aligned
file size to file_ram_alloc().


+memory_region_set_size(block->mr, mem_size);


This could be simplified (and made safer) if the memory region
got initialized by memory_region_init_ram_from_file() after we
already mapped/allocated the file (so we avoid surprises in case
other code does something weird because of the temporarily
zero-sized MemoryRegion). But it would probably be an intrusive
change, so I guess changing the memory size here is OK. Paolo,
what do you think?



I will add a check to ensure that the size of block->mr is either 0 or
mem_size, and only set the region size in the former case. The former
corresponds to the case that 'size' option is not given or 0. The
latter corresponds to the case that 'size' option is given.


+}
+
+if (mem_size < block->page_size) {
 error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
"or larger than page size 0x%zx",
-   memory, block->page_size);
+   mem_size, block->page_size);
 goto error;
 }

-if (file_size > 0 && file_size < memory) {
+if (file_size > 0 && file_size < mem_size) {
 error_setg(errp, "backing store %s size %"PRId64
" does not match 'size' option %"PRIu64,
-   path, file_size, 

[Qemu-devel] [PULL 50/73] adb: change handler only when recognized

2016-10-27 Thread David Gibson
From: Hervé Poussineau 

ADB devices must take new handler into account only when they recognize it.
This lets operating systems probe for valid/invalid handles, to know device 
capabilities.

Add a FIXME in keyboard handler, which should use a different translation
table depending of the selected handler.

Signed-off-by: Hervé Poussineau 
Signed-off-by: David Gibson 
---
 hw/input/adb.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/hw/input/adb.c b/hw/input/adb.c
index 3d39368..43d3205 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -396,9 +396,15 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 d->devaddr = buf[1] & 0xf;
 break;
 default:
-/* XXX: check this */
 d->devaddr = buf[1] & 0xf;
-d->handler = buf[2];
+/* we support handlers:
+ * 1: Apple Standard Keyboard
+ * 2: Apple Extended Keyboard (LShift = RShift)
+ * 3: Apple Extended Keyboard (LShift != RShift)
+ */
+if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
+d->handler = buf[2];
+}
 break;
 }
 }
@@ -437,6 +443,7 @@ static void adb_keyboard_event(DeviceState *dev, 
QemuConsole *src,
 if (qcode >= ARRAY_SIZE(qcode_to_adb_keycode)) {
 return;
 }
+/* FIXME: take handler into account when translating qcode */
 keycode = qcode_to_adb_keycode[qcode];
 if (keycode == NO_KEY) {  /* We don't want to send this to the guest */
 ADB_DPRINTF("Ignoring NO_KEY\n");
@@ -631,8 +638,21 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 d->devaddr = buf[1] & 0xf;
 break;
 default:
-/* XXX: check this */
 d->devaddr = buf[1] & 0xf;
+/* we support handlers:
+ * 0x01: Classic Apple Mouse Protocol / 100 cpi operations
+ * 0x02: Classic Apple Mouse Protocol / 200 cpi operations
+ * we don't support handlers (at least):
+ * 0x03: Mouse systems A3 trackball
+ * 0x04: Extended Apple Mouse Protocol
+ * 0x2f: Microspeed mouse
+ * 0x42: Macally
+ * 0x5f: Microspeed mouse
+ * 0x66: Microspeed mouse
+ */
+if (buf[2] == 1 || buf[2] == 2) {
+d->handler = buf[2];
+}
 break;
 }
 }
-- 
2.7.4




[Qemu-devel] [PULL 73/73] ppc: allow certain HV interrupts to be delivered to guests

2016-10-27 Thread David Gibson
From: Nicholas Piggin 

ppc hypervisors have delivered system reset and machine check exception
interrupts to guests in some situations (e.g., see FWNMI feature of LoPAPR,
or NMI injection in QEMU).

These exceptions are architected to set the HV bit in hardware, however
when injected into a guest, the HV bit should be cleared. Current code
masks off the HV bit before setting the new MSR, however this happens after
the interrupt delivery model has calculated delivery mode for the exception.
This can result in the guest's MSR LE bit being lost.

Account for this in the exception handler and don't set HV bit for guest
delivery.

Also add another sanity check to ensure similar bugs get caught.

Signed-off-by: Nicholas Piggin 
Signed-off-by: David Gibson 
---
 target-ppc/excp_helper.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 53c4075..808760b 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -213,7 +213,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 cs->halted = 1;
 cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 }
-new_msr |= (target_ulong)MSR_HVB;
+if (env->msr_mask & MSR_HVB) {
+/* ISA specifies HV, but can be delivered to guest with HV clear
+ * (e.g., see FWNMI in PAPR).
+ */
+new_msr |= (target_ulong)MSR_HVB;
+}
 ail = 0;
 
 /* machine check exceptions don't have ME set */
@@ -391,8 +396,17 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 msr |= 0x1;
 new_msr |= ((target_ulong)1 << MSR_ME);
 }
-
-new_msr |= (target_ulong)MSR_HVB;
+if (env->msr_mask & MSR_HVB) {
+/* ISA specifies HV, but can be delivered to guest with HV clear
+ * (e.g., see FWNMI in PAPR, NMI injection in QEMU).
+ */
+new_msr |= (target_ulong)MSR_HVB;
+} else {
+if (msr_pow) {
+cpu_abort(cs, "Trying to deliver power-saving system reset "
+  "exception %d with no HV support\n", excp);
+}
+}
 ail = 0;
 break;
 case POWERPC_EXCP_DSEG:  /* Data segment exception   */
@@ -609,9 +623,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 env->spr[srr1] = msr;
 
 /* Sanity check */
-if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) {
-cpu_abort(cs, "Trying to deliver HV exception %d with "
-  "no HV support\n", excp);
+if (!(env->msr_mask & MSR_HVB)) {
+if (new_msr & MSR_HVB) {
+cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
+  "no HV support\n", excp);
+}
+if (srr0 == SPR_HSRR0) {
+cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
+  "no HV support\n", excp);
+}
 }
 
 /* If any alternate SRR register are defined, duplicate saved values */
-- 
2.7.4




[Qemu-devel] [PATCH v1 1/1] virtio crypto device specification: asymmetric crypto service

2016-10-27 Thread Xin Zeng
This patch introduces asymmetric crypto service into virtio crypto
device spec. The asymmetric crypto service can be referred as signature,
verification, encryption, decryption, key generation and key exchange.
This patch depends on another virtio crypto device spec patch:
https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg01744.html

Changes since v0:
- Use devicenormative/drivernormative instead of self-defined
  device/driver label.  [Lei]
- Change the error code of verification to general virtio_crypto
  error code. [Lei]
- Use macro instead of enum in verification result. [Lei]
- Fix the incorrect label value for paragraph and section. [Lei]

Please help to review, thanks!

Signed-off-by: Xin Zeng 
---
 virtio-crypto.tex | 965 +-
 1 file changed, 962 insertions(+), 3 deletions(-)

diff --git a/virtio-crypto.tex b/virtio-crypto.tex
index 86e4869..43772da 100644
--- a/virtio-crypto.tex
+++ b/virtio-crypto.tex
@@ -6,7 +6,7 @@ decryption requests are placed in the data queue and are 
ultimately handled by t
 backend crypto accelerators. The second queue is the control queue used to 
create 
 or destroy sessions for symmetric algorithms and will control some advanced
 features in the future. The virtio crypto device provides the following crypto
-services: CIPHER, MAC, HASH, and AEAD.
+services: CIPHER, MAC, HASH, AEAD and ASYM.
 
 
 \subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}
@@ -44,7 +44,9 @@ struct virtio_crypto_config {
 le32 mac_algo_l;
 le32 mac_algo_h;
 le32 aead_algo;
-le32 reserve;
+le32 asym_algo;
+le32 rsa_padding;
+le32 reserved;
 };
 \end{lstlisting}
 
@@ -70,6 +72,8 @@ The following services are defined:
 #define VIRTIO_CRYPTO_SERVICE_MAC(2)
 /* AEAD (Authenticated Encryption with Associated Data) service */
 #define VIRTIO_CRYPTO_SERVICE_AEAD   (3)
+/* ASYM (Asymmetric crypto algorithms) service */
+#define VIRTIO_CRYPTO_SERVICE_ASYM   (4)
 \end{lstlisting}
 
 The last driver-read-only fields specify detailed algorithms masks 
@@ -143,6 +147,28 @@ The following AEAD algorithms are defined:
 #define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
 \end{lstlisting}
 
+The following asymmetric algorithms are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_ASYM_NONE0
+#define VIRTIO_CRYPTO_ASYM_RSA 1
+#define VIRTIO_CRYPTO_ASYM_DSA 2
+#define VIRTIO_CRYPTO_ASYM_DH  3
+#define VIRTIO_CRYPTO_ASYM_ECDSA   4
+#define VIRTIO_CRYPTO_ASYM_ECDH   5
+\end{lstlisting}
+
+The following rsa padding capabilities are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_RSA_NO_PADDING 0
+#define VIRTIO_CRYPTO_RSA_PKCS1_PADDING  1
+#define VIRTIO_CRYPTO_RSA_SSLV23_PADDING 2
+#define VIRTIO_CRYPTO_RSA_PKCS1_OAEP_PADDING 3
+#define VIRTIO_CRYPTO_RSA_X931_PADDING   4
+#define VIRTIO_CRYPTO_RSA_PKCS1_PSS_PADDING  5
+\end{lstlisting}
+
 \begin{note}
 Any other value is reserved for future use.
 \end{note}
@@ -241,6 +267,18 @@ struct virtio_crypto_op_header {
 VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
 #define VIRTIO_CRYPTO_AEAD_DECRYPT \
 VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
+#define VIRTIO_CRYPTO_ASYM_SIGN\
+VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_ASYM, 0x00)
+#define VIRTIO_CRYPTO_ASYM_VERIFY \
+VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_ASYM, 0x01)
+#define VIRTIO_CRYPTO_ASYM_ENCRYPT  \
+VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_ASYM, 0x02)
+#define VIRTIO_CRYPTO_ASYM_DECRYPT  \
+VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_ASYM, 0x03)
+#define VIRTIO_CRYPTO_ASYM_KEY_GEN  \
+VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_ASYM, 0x04)
+#define VIRTIO_CRYPTO_ASYM_KEY_EXCHG \
+VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_ASYM, 0x05)
 le32 opcode;
 /* algo should be service-specific algorithms */
 le32 algo;
@@ -548,6 +586,23 @@ struct virtio_crypto_op_data_req {
 struct virtio_crypto_hash_data_req  hash_req;
 struct virtio_crypto_mac_data_req   mac_req;
 struct virtio_crypto_aead_data_req  aead_req;
+
+struct virtio_crypto_ecdsa_sign_req ecdsa_sign_req;
+struct virtio_crypto_dsa_sign_req dsa_sign_req;
+struct virtio_crypto_rsa_sign_req rsa_sign_req;
+struct virtio_crypto_ecdsa_verify_req ecdsa_verify_req;
+struct virtio_crypto_dsa_verify_req dsa_verify_req;
+struct virtio_crypto_rsa_verify_req rsa_verify_req;
+struct virtio_crypto_rsa_enc_req rsa_enc_req
+struct virtio_crypto_rsa_dec_req rsa_dec_req;
+struct virtio_crypto_rsa_keygen_req rsa_keygen_req;
+struct virtio_crypto_dsa_keygen_req dsa_keygen_req;
+struct virtio_crypto_ec_keygen_req ec_keygen_req;
+struct virtio_crypto_dh_keyexchg_param_gen_req 
dh_keyexchg_param_gen_req;
+struct virtio_crypto_dh_keyexchg_key_gen_req 

Re: [Qemu-devel] [PATCH v2 1/3] exec.c: do not truncate non-empty memory backend file

2016-10-27 Thread Haozhong Zhang

On 10/27/16 12:31 -0200, Eduardo Habkost wrote:

On Thu, Oct 27, 2016 at 12:22:58PM +0800, Haozhong Zhang wrote:

For '-object memory-backend-file,mem-path=foo,size=xyz', if the size of
file 'foo' does not match the given size 'xyz', the current QEMU will
truncate the file to the given size, which may corrupt the existing data
in that file. To avoid such data corruption, this patch disables
truncating non-empty backend files.

Signed-off-by: Haozhong Zhang 


Reviewed-by: Eduardo Habkost 

But I would add comment near the get_file_size() call to indicate
that not stopping on get_file_size() errors is on purpose and not
a mistake.



I'll add comments in the next version.

Thanks,
Haozhong


---
 exec.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 587b489..a2b371a 100644
--- a/exec.c
+++ b/exec.c
@@ -1224,6 +1224,15 @@ void qemu_mutex_unlock_ramlist(void)
 }

 #ifdef __linux__
+static int64_t get_file_size(int fd)
+{
+int64_t size = lseek(fd, 0, SEEK_END);
+if (size < 0) {
+return -errno;
+}
+return size;
+}
+
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path,
@@ -1235,6 +1244,7 @@ static void *file_ram_alloc(RAMBlock *block,
 char *c;
 void *area = MAP_FAILED;
 int fd = -1;
+int64_t file_size;

 if (kvm_enabled() && !kvm_has_sync_mmu()) {
 error_setg(errp,
@@ -1297,6 +1307,8 @@ static void *file_ram_alloc(RAMBlock *block,
 }
 #endif

+file_size = get_file_size(fd);
+
 if (memory < block->page_size) {
 error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
"or larger than page size 0x%zx",
@@ -1311,8 +1323,16 @@ static void *file_ram_alloc(RAMBlock *block,
  * hosts, so don't bother bailing out on errors.
  * If anything goes wrong with it under other filesystems,
  * mmap will fail.
+ *
+ * Do not truncate the non-empty backend file to avoid corrupting
+ * the existing data in the file. Disabling shrinking is not
+ * enough. For example, the current vNVDIMM implementation stores
+ * the guest NVDIMM labels at the end of the backend file. If the
+ * backend file is later extended, QEMU will not be able to find
+ * those labels. Therefore, extending the non-empty backend file
+ * is disabled as well.
  */
-if (ftruncate(fd, memory)) {
+if (!file_size && ftruncate(fd, memory)) {
 perror("ftruncate");
 }

--
2.10.1



--
Eduardo




[Qemu-devel] [PULL 68/73] spapr_events: add support for dedicated hotplug event source

2016-10-27 Thread David Gibson
From: Michael Roth 

Hotplug events were previously delivered using an EPOW interrupt
and were queued by linux guests into a circular buffer. For traditional
EPOW events like shutdown/resets, this isn't an issue, but for hotplug
events there are cases where this buffer can be exhausted, resulting
in the loss of hotplug events, resets, etc.

Newer-style hotplug event are delivered using a dedicated event source.
We enable this in supported guests by adding standard an additional
event source in the guest device-tree via /event-sources, and, if
the guest advertises support for the newer-style hotplug events,
using the corresponding interrupt to signal the available of
hotplug/unplug events.

Signed-off-by: Michael Roth 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  |   9 +-
 hw/ppc/spapr_events.c   | 202 
 include/hw/ppc/spapr.h  |   6 +-
 include/hw/ppc/spapr_ovec.h |   1 +
 4 files changed, 177 insertions(+), 41 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 0b3820b..9ddf2ff 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -973,7 +973,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 }
 
 /* /event-sources */
-spapr_dt_events(fdt, spapr->check_exception_irq);
+spapr_dt_events(spapr, fdt);
 
 /* /rtas */
 spapr_dt_rtas(spapr, fdt);
@@ -1789,6 +1789,11 @@ static void ppc_spapr_init(MachineState *machine)
 
 spapr_ovec_set(spapr->ov5, OV5_FORM1_AFFINITY);
 
+/* advertise support for dedicated HP event source to guests */
+if (spapr->use_hotplug_event_source) {
+spapr_ovec_set(spapr->ov5, OV5_HP_EVT);
+}
+
 /* init CPUs */
 if (machine->cpu_model == NULL) {
 machine->cpu_model = kvm_enabled() ? "host" : smc->tcg_default_cpu;
@@ -1912,7 +1917,7 @@ static void ppc_spapr_init(MachineState *machine)
 }
 g_free(filename);
 
-/* Set up EPOW events infrastructure */
+/* Set up RTAS event infrastructure */
 spapr_events_init(spapr);
 
 /* Set up the RTC RTAS interfaces */
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 89aa5a7..9b0bd41 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -40,6 +40,7 @@
 #include "hw/ppc/spapr_drc.h"
 #include "qemu/help_option.h"
 #include "qemu/bcd.h"
+#include "hw/ppc/spapr_ovec.h"
 #include 
 
 struct rtas_error_log {
@@ -206,27 +207,132 @@ struct hp_log_full {
 struct rtas_event_log_v6_hp hp;
 } QEMU_PACKED;
 
-#define EVENT_MASK_INTERNAL_ERRORS   0x8000
-#define EVENT_MASK_EPOW  0x4000
-#define EVENT_MASK_HOTPLUG   0x1000
-#define EVENT_MASK_IO0x0800
+typedef enum EventClass {
+EVENT_CLASS_INTERNAL_ERRORS = 0,
+EVENT_CLASS_EPOW= 1,
+EVENT_CLASS_RESERVED= 2,
+EVENT_CLASS_HOT_PLUG= 3,
+EVENT_CLASS_IO  = 4,
+EVENT_CLASS_MAX
+} EventClassIndex;
+#define EVENT_CLASS_MASK(index) (1 << (31 - index))
+
+static const char * const event_names[EVENT_CLASS_MAX] = {
+[EVENT_CLASS_INTERNAL_ERRORS]   = "internal-errors",
+[EVENT_CLASS_EPOW]  = "epow-events",
+[EVENT_CLASS_HOT_PLUG]  = "hot-plug-events",
+[EVENT_CLASS_IO]= "ibm,io-events",
+};
+
+struct sPAPREventSource {
+int irq;
+uint32_t mask;
+bool enabled;
+};
+
+static sPAPREventSource *spapr_event_sources_new(void)
+{
+return g_new0(sPAPREventSource, EVENT_CLASS_MAX);
+}
+
+static void spapr_event_sources_register(sPAPREventSource *event_sources,
+EventClassIndex index, int irq)
+{
+/* we only support 1 irq per event class at the moment */
+g_assert(event_sources);
+g_assert(!event_sources[index].enabled);
+event_sources[index].irq = irq;
+event_sources[index].mask = EVENT_CLASS_MASK(index);
+event_sources[index].enabled = true;
+}
+
+static const sPAPREventSource *
+spapr_event_sources_get_source(sPAPREventSource *event_sources,
+   EventClassIndex index)
+{
+g_assert(index < EVENT_CLASS_MAX);
+g_assert(event_sources);
+
+return _sources[index];
+}
 
-void spapr_dt_events(void *fdt, uint32_t check_exception_irq)
+void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
 {
-int event_sources, epow_events;
-uint32_t irq_ranges[] = {cpu_to_be32(check_exception_irq), cpu_to_be32(1)};
-uint32_t interrupts[] = {cpu_to_be32(check_exception_irq), 0};
+uint32_t irq_ranges[EVENT_CLASS_MAX * 2];
+int i, count = 0, event_sources;
+sPAPREventSource *events = spapr->event_sources;
+
+g_assert(events);
 
 _FDT(event_sources = fdt_add_subnode(fdt, 0, "event-sources"));
 
-_FDT(fdt_setprop(fdt, event_sources, "interrupt-controller", NULL, 0));
-

[Qemu-devel] [PULL 72/73] spapr: Memory hot-unplug support

2016-10-27 Thread David Gibson
From: Bharata B Rao 

Add support to hot remove pc-dimm memory devices.

Since we're introducing a machine-level unplug_request hook, we also
had handling for CPU unplug there as well to ensure CPU unplug
continues to work as it did before.

Signed-off-by: Bharata B Rao 
* add hooks to CAS/cmdline enablement of hotplug ACR support
* add hook for CPU unplug
Signed-off-by: Michael Roth 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 119 -
 hw/ppc/spapr_drc.c |  17 
 2 files changed, 135 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 531dfeb..c8e2921 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2281,6 +2281,90 @@ out:
 error_propagate(errp, local_err);
 }
 
+typedef struct sPAPRDIMMState {
+uint32_t nr_lmbs;
+} sPAPRDIMMState;
+
+static void spapr_lmb_release(DeviceState *dev, void *opaque)
+{
+sPAPRDIMMState *ds = (sPAPRDIMMState *)opaque;
+HotplugHandler *hotplug_ctrl;
+
+if (--ds->nr_lmbs) {
+return;
+}
+
+g_free(ds);
+
+/*
+ * Now that all the LMBs have been removed by the guest, call the
+ * pc-dimm unplug handler to cleanup up the pc-dimm device.
+ */
+hotplug_ctrl = qdev_get_hotplug_handler(dev);
+hotplug_handler_unplug(hotplug_ctrl, dev, _abort);
+}
+
+static void spapr_del_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t 
size,
+   Error **errp)
+{
+sPAPRDRConnector *drc;
+sPAPRDRConnectorClass *drck;
+uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
+int i;
+sPAPRDIMMState *ds = g_malloc0(sizeof(sPAPRDIMMState));
+uint64_t addr = addr_start;
+
+ds->nr_lmbs = nr_lmbs;
+for (i = 0; i < nr_lmbs; i++) {
+drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
+addr / SPAPR_MEMORY_BLOCK_SIZE);
+g_assert(drc);
+
+drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+drck->detach(drc, dev, spapr_lmb_release, ds, errp);
+addr += SPAPR_MEMORY_BLOCK_SIZE;
+}
+
+drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
+   addr_start / SPAPR_MEMORY_BLOCK_SIZE);
+drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+spapr_hotplug_req_remove_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
+  nr_lmbs,
+  drck->get_index(drc));
+}
+
+static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
+Error **errp)
+{
+sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev);
+PCDIMMDevice *dimm = PC_DIMM(dev);
+PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
+MemoryRegion *mr = ddc->get_memory_region(dimm);
+
+pc_dimm_memory_unplug(dev, >hotplug_memory, mr);
+object_unparent(OBJECT(dev));
+}
+
+static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+Error *local_err = NULL;
+PCDIMMDevice *dimm = PC_DIMM(dev);
+PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
+MemoryRegion *mr = ddc->get_memory_region(dimm);
+uint64_t size = memory_region_size(mr);
+uint64_t addr;
+
+addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, 
_err);
+if (local_err) {
+goto out;
+}
+
+spapr_del_lmbs(dev, addr, size, _abort);
+out:
+error_propagate(errp, local_err);
+}
+
 void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
 sPAPRMachineState *spapr)
 {
@@ -2354,10 +2438,42 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
 static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
+sPAPRMachineState *sms = SPAPR_MACHINE(qdev_get_machine());
 MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-error_setg(errp, "Memory hot unplug not supported by sPAPR");
+if (spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) {
+spapr_memory_unplug(hotplug_dev, dev, errp);
+} else {
+error_setg(errp, "Memory hot unplug not supported for this guest");
+}
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
+if (!mc->query_hotpluggable_cpus) {
+error_setg(errp, "CPU hot unplug not supported on this machine");
+return;
+}
+spapr_core_unplug(hotplug_dev, dev, errp);
+}
+}
+
+static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+

[Qemu-devel] [PULL 61/73] tests: Don't assume structure of PCI IO base in ahci-test

2016-10-27 Thread David Gibson
In a couple of places ahci-test makes assumptions about how the tokens
returned from qpci_iomap() are formatted in ways it probably shouldn't.

First in verify_state() it uses a non-NULL token to indicate that the AHCI
device has been enabled (part of enabling is to iomap()).  This changes it
to use an explicit 'enabled' flag instead.

Second, it uses the fact that the token contains a PCI address, stored when
the BAR is mapped during initialization to check that the BAR has the same
value after a migration.  This changes it to explicitly read the BAR
register before and after the migration and compare.

Together, these changes will  make the test more robust against changes to
the internals of the libqos PCI layer.

Signed-off-by: David Gibson 
Reviewed-by: John Snow 
Reviewed-by: Greg Kurz 
---
 tests/ahci-test.c   | 13 +++--
 tests/libqos/ahci.c |  1 +
 tests/libqos/ahci.h |  1 +
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 9c0adce..70bcafa 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -78,25 +78,23 @@ static void string_bswap16(uint16_t *s, size_t bytes)
 /**
  * Verify that the transfer did not corrupt our state at all.
  */
-static void verify_state(AHCIQState *ahci)
+static void verify_state(AHCIQState *ahci, uint64_t hba_old)
 {
 int i, j;
 uint32_t ahci_fingerprint;
 uint64_t hba_base;
-uint64_t hba_stored;
 AHCICommandHeader cmd;
 
 ahci_fingerprint = qpci_config_readl(ahci->dev, PCI_VENDOR_ID);
 g_assert_cmphex(ahci_fingerprint, ==, ahci->fingerprint);
 
 /* If we haven't initialized, this is as much as can be validated. */
-if (!ahci->hba_base) {
+if (!ahci->enabled) {
 return;
 }
 
 hba_base = (uint64_t)qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5);
-hba_stored = (uint64_t)(uintptr_t)ahci->hba_base;
-g_assert_cmphex(hba_base, ==, hba_stored);
+g_assert_cmphex(hba_base, ==, hba_old);
 
 g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP), ==, ahci->cap);
 g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP2), ==, ahci->cap2);
@@ -119,12 +117,15 @@ static void ahci_migrate(AHCIQState *from, AHCIQState 
*to, const char *uri)
 QOSState *tmp = to->parent;
 QPCIDevice *dev = to->dev;
 char *uri_local = NULL;
+uint64_t hba_old;
 
 if (uri == NULL) {
 uri_local = g_strdup_printf("%s%s", "unix:", mig_socket);
 uri = uri_local;
 }
 
+hba_old = (uint64_t)qpci_config_readl(from->dev, PCI_BASE_ADDRESS_5);
+
 /* context will be 'to' after completion. */
 migrate(from->parent, to->parent, uri);
 
@@ -141,7 +142,7 @@ static void ahci_migrate(AHCIQState *from, AHCIQState *to, 
const char *uri)
 from->parent = tmp;
 from->dev = dev;
 
-verify_state(to);
+verify_state(to, hba_old);
 g_free(uri_local);
 }
 
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 716ab79..8e789d8 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -351,6 +351,7 @@ void ahci_hba_enable(AHCIQState *ahci)
 reg = ahci_rreg(ahci, AHCI_GHC);
 ASSERT_BIT_SET(reg, AHCI_GHC_IE);
 
+ahci->enabled = true;
 /* TODO: The device should now be idling and waiting for commands.
  * In the future, a small test-case to inspect the Register D2H FIS
  * and clear the initial interrupts might be good. */
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index c69fb5a..9b0c1d7 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -327,6 +327,7 @@ typedef struct AHCIQState {
 uint32_t cap;
 uint32_t cap2;
 AHCIPortQState port[32];
+bool enabled;
 } AHCIQState;
 
 /**
-- 
2.7.4




[Qemu-devel] [PULL 63/73] spapr_nvram: Pre-initialize the NVRAM to support the -prom-env parameter

2016-10-27 Thread David Gibson
From: Thomas Huth 

In case we do not load the NVRAM contents from a file and the user
specified the "-prom-env" parameter, use the new CHRP NVRAM helper
functions to pre-initialize the NVRAM partitions, so that the SLOF
firmware now can pick up the environment variables from the -prom-env
parameter, too.

Signed-off-by: Thomas Huth 
Signed-off-by: David Gibson 
---
 hw/nvram/spapr_nvram.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index 4de5f70..eb42ea3 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -31,6 +31,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/device_tree.h"
 #include "hw/sysbus.h"
+#include "hw/nvram/chrp_nvram.h"
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 
@@ -162,6 +163,11 @@ static void spapr_nvram_realize(VIOsPAPRDevice *dev, Error 
**errp)
 error_setg(errp, "can't read spapr-nvram contents");
 return;
 }
+} else if (nb_prom_envs > 0) {
+/* Create a system partition to pass the -prom-env variables */
+chrp_nvram_create_system_partition(nvram->buf, MIN_NVRAM_SIZE / 4);
+chrp_nvram_create_free_partition(>buf[MIN_NVRAM_SIZE / 4],
+ nvram->size - MIN_NVRAM_SIZE / 4);
 }
 
 spapr_rtas_register(RTAS_NVRAM_FETCH, "nvram-fetch", rtas_nvram_fetch);
-- 
2.7.4




[Qemu-devel] [PULL 54/73] libqos: Better handling of PCI legacy IO

2016-10-27 Thread David Gibson
The usual model for PCI IO with libqos is to use qpci_iomap() to map a
specific BAR for a PCI device, then perform IOs within that BAR using
qpci_io_{read,write}*().

However, certain devices also have legacy PCI IO.  In this case, instead of
(or as well as) being accessed via PCI BARs, the device can be accessed
via certain well-known, fixed addresses in PCI IO space.

Two existing tests use legacy PCI IO, and take different flawed approaches
to it:
* tco-test manually constructs a tco_io_base value instead of calling
  qpci_iomap(), which assumes internal knowledge of the structure of
  the value it shouldn't have
* ide-test uses direct in*() and out*() calls instead of using
  qpci_io_*() accessors, meaning it's not portable to non-x86 machine
  types.

This patch implements a new qpci_iomap_legacy() interface which gets a
handle in the same format as qpci_iomap() but refers to a region in
the legacy PIO space.  For a device which has the same registers
available both in a BAR and in legacy space (quite common), this
allows the same test code to test both options with just a different
iomap() at the beginning.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/pci.c | 5 +
 tests/libqos/pci.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index bf1c532..98a2e56 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -350,6 +350,11 @@ void qpci_iounmap(QPCIDevice *dev, void *data)
 /* FIXME */
 }
 
+void *qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
+{
+return (void *)(uintptr_t)addr;
+}
+
 void qpci_plug_device_test(const char *driver, const char *id,
uint8_t slot, const char *opts)
 {
diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index f6f916d..b6f855e 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -94,6 +94,7 @@ void qpci_io_writel(QPCIDevice *dev, void *data, uint32_t 
value);
 
 void *qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr);
 void qpci_iounmap(QPCIDevice *dev, void *data);
+void *qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr);
 
 void qpci_plug_device_test(const char *driver, const char *id,
uint8_t slot, const char *opts);
-- 
2.7.4




[Qemu-devel] [PULL 67/73] spapr: update spapr hotplug documentation

2016-10-27 Thread David Gibson
From: Michael Roth 

This updates the existing documentation to reflect recent updates to
the hotplug event structure, which are in draft form but slated
for inclusion in PAPR/LoPAPR.

Signed-off-by: Michael Roth 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 docs/specs/ppc-spapr-hotplug.txt | 55 +---
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/docs/specs/ppc-spapr-hotplug.txt b/docs/specs/ppc-spapr-hotplug.txt
index 631b0ca..f57e2a0 100644
--- a/docs/specs/ppc-spapr-hotplug.txt
+++ b/docs/specs/ppc-spapr-hotplug.txt
@@ -233,12 +233,27 @@ tools by host-level management such as an HMC. This level 
of management is not
 applicable to PowerKVM, hence the reason for extending the notification
 framework to support hotplug events.
 
-Note that these events are not yet formally part of the PAPR+ specification,
-but support for this format has already been implemented in DR-related
-guest tools such as powerpc-utils/librtas, as well as kernel patches that have
-been submitted to handle in-kernel processing of memory/cpu-related hotplug
-events[1], and is planned for formal inclusion is PAPR+ specification. The
-hotplug-specific payload is QEMU implemented as follows (with all values
+The format for these EPOW-signalled events is described below under
+"hotplug/unplug event structure". Note that these events are not
+formally part of the PAPR+ specification, and have been superseded by a
+newer format, also described below under "hotplug/unplug event structure",
+and so are now deemed a "legacy" format. The formats are similar, but the
+"modern" format contains additional fields/flags, which are denoted for the
+purposes of this documentation with "#ifdef GUEST_SUPPORTS_MODERN" guards.
+
+QEMU should assume support only for "legacy" fields/flags unless the guest
+advertises support for the "modern" format via ibm,client-architecture-support
+hcall by setting byte 5, bit 6 of it's ibm,architecture-vec-5 option vector
+structure (as described by LoPAPR v11, B.6.2.3). As with "legacy" format 
events,
+"modern" format events are surfaced to the guest via check-exception RTAS 
calls,
+but use a dedicated event source to signal the guest. This event source is
+advertised to the guest by the addition of a "hot-plug-events" node under
+"/event-sources" node of the guest's device tree using the standard format
+described in LoPAPR v11, B.6.12.1.
+
+== hotplug/unplug event structure ==
+
+The hotplug-specific payload in QEMU is implemented as follows (with all values
 encoded in big-endian format):
 
 struct rtas_event_log_v6_hp {
@@ -263,14 +278,23 @@ struct rtas_event_log_v6_hp {
 #define RTAS_LOG_V6_HP_ACTION_ADD   1
 #define RTAS_LOG_V6_HP_ACTION_REMOVE2
 uint8_t hotplug_action; /* action (add/remove) */
-#define RTAS_LOG_V6_HP_ID_DRC_NAME  1
-#define RTAS_LOG_V6_HP_ID_DRC_INDEX 2
-#define RTAS_LOG_V6_HP_ID_DRC_COUNT 3
+#define RTAS_LOG_V6_HP_ID_DRC_NAME  1
+#define RTAS_LOG_V6_HP_ID_DRC_INDEX 2
+#define RTAS_LOG_V6_HP_ID_DRC_COUNT 3
+#ifdef GUEST_SUPPORTS_MODERN
+#define RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED 4
+#endif
 uint8_t hotplug_identifier; /* type of the resource identifier,
  * which serves as the discriminator
  * for the 'drc' union field below
  */
+#ifdef GUEST_SUPPORTS_MODERN
+uint8_t capabilities;   /* capability flags, currently unused
+ * by QEMU
+ */
+#else
 uint8_t reserved;
+#endif
 union {
 uint32_t index; /* DRC index of resource to take action
  * on
@@ -278,6 +302,19 @@ struct rtas_event_log_v6_hp {
 uint32_t count; /* number of DR resources to take
  * action on (guest chooses which)
  */
+#ifdef GUEST_SUPPORTS_MODERN
+struct {
+uint32_t count; /* number of DR resources to take
+ * action on
+ */
+uint32_t index; /* DRC index of first resource to take
+ * action on. guest will take action
+ * on DRC index  through
+ * DRC index  in
+ * sequential order
+ */
+} count_indexed;
+#endif
 char name[1];   /* string representing the name of the
  * DRC to take action 

[Qemu-devel] [PULL 57/73] libqos: Implement mmio accessors in terms of mem{read, write}

2016-10-27 Thread David Gibson
In the libqos PCI code we now have accessors both for registers (byte
significance preserving) and for streaming data (byte address order
preserving).  These exist in both the interface for qtest drivers and in
the machine specific backends.

However, the register-style accessors aren't actually necessary in the
backend.  They can be implemented in terms of the byte address order
preserving accessors by the libqos wrappers.  This works because PCI is
always little endian.

This does assume that the back end byte address order preserving accessors
will perform the equivalent of a single bus transaction for short lengths.
This is the case, and in fact they currently end up using the same
cpu_physical_memory_rw() implementation within the qtest accelerator.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/pci-pc.c| 38 --
 tests/libqos/pci-spapr.c | 44 
 tests/libqos/pci.c   | 20 ++--
 tests/libqos/pci.h   |  8 
 4 files changed, 14 insertions(+), 96 deletions(-)

diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 84aee25..849ea56 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -32,61 +32,31 @@ static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t 
addr)
 return inb(addr);
 }
 
-static uint8_t qpci_pc_mmio_readb(QPCIBus *bus, uint32_t addr)
-{
-return readb(addr);
-}
-
 static void qpci_pc_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
 {
 outb(addr, val);
 }
 
-static void qpci_pc_mmio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
-{
-writeb(addr, val);
-}
-
 static uint16_t qpci_pc_pio_readw(QPCIBus *bus, uint32_t addr)
 {
 return inw(addr);
 }
 
-static uint16_t qpci_pc_mmio_readw(QPCIBus *bus, uint32_t addr)
-{
-return readw(addr);
-}
-
 static void qpci_pc_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
 {
 outw(addr, val);
 }
 
-static void qpci_pc_mmio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
-{
-writew(addr, val);
-}
-
 static uint32_t qpci_pc_pio_readl(QPCIBus *bus, uint32_t addr)
 {
 return inl(addr);
 }
 
-static uint32_t qpci_pc_mmio_readl(QPCIBus *bus, uint32_t addr)
-{
-return readl(addr);
-}
-
 static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
 {
 outl(addr, val);
 }
 
-static void qpci_pc_mmio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
-{
-writel(addr, val);
-}
-
 static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
 {
 memread(addr, buf, len);
@@ -148,14 +118,6 @@ QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 ret->bus.pio_writew = qpci_pc_pio_writew;
 ret->bus.pio_writel = qpci_pc_pio_writel;
 
-ret->bus.mmio_readb = qpci_pc_mmio_readb;
-ret->bus.mmio_readw = qpci_pc_mmio_readw;
-ret->bus.mmio_readl = qpci_pc_mmio_readl;
-
-ret->bus.mmio_writeb = qpci_pc_mmio_writeb;
-ret->bus.mmio_writew = qpci_pc_mmio_writew;
-ret->bus.mmio_writel = qpci_pc_mmio_writel;
-
 ret->bus.memread = qpci_pc_memread;
 ret->bus.memwrite = qpci_pc_memwrite;
 
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index ad12c2e..f26488a 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -48,72 +48,36 @@ static uint8_t qpci_spapr_pio_readb(QPCIBus *bus, uint32_t 
addr)
 return readb(s->pio_cpu_base + addr);
 }
 
-static uint8_t qpci_spapr_mmio32_readb(QPCIBus *bus, uint32_t addr)
-{
-QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-return readb(s->mmio32_cpu_base + addr);
-}
-
 static void qpci_spapr_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
 {
 QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
 writeb(s->pio_cpu_base + addr, val);
 }
 
-static void qpci_spapr_mmio32_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
-{
-QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-writeb(s->mmio32_cpu_base + addr, val);
-}
-
 static uint16_t qpci_spapr_pio_readw(QPCIBus *bus, uint32_t addr)
 {
 QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
 return bswap16(readw(s->pio_cpu_base + addr));
 }
 
-static uint16_t qpci_spapr_mmio32_readw(QPCIBus *bus, uint32_t addr)
-{
-QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-return bswap16(readw(s->mmio32_cpu_base + addr));
-}
-
 static void qpci_spapr_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
 {
 QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
 writew(s->pio_cpu_base + addr, bswap16(val));
 }
 
-static void qpci_spapr_mmio32_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
-{
-QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-writew(s->mmio32_cpu_base + addr, bswap16(val));
-}
-
 static uint32_t qpci_spapr_pio_readl(QPCIBus *bus, uint32_t addr)
 {
 QPCIBusSPAPR *s = container_of(bus, 

[Qemu-devel] [PULL 53/73] libqos: Move BAR assignment to common code

2016-10-27 Thread David Gibson
The PCI backends in libqos each supply an iomap() and iounmap() function
which is used to set up a specified PCI BAR.  But PCI BAR allocation takes
place entirely within PCI space, so doesn't really need per-backend
versions.  For example, Linux includes generic BAR allocation code used on
platforms where that isn't done by firmware.

This patch merges the BAR allocation from the two existing backends into a
single simplified copy.  The back ends just need to set up some parameters
describing the window of PCI IO and PCI memory addresses which are
available for allocation.  Like both the existing versions the new one uses
a simple bump allocator.

Note that (again like the existing versions) this doesn't really handle
64-bit memory BARs properly.  It is actually used for such a BAR by the
ivshmem test, and apparently the 32-bit MMIO BAR logic is close enough to
work, as long as the BAR isn't too big.  Fixing that to properly handle
64-bit BAR allocation is a problem for another time.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/pci-pc.c| 87 ++
 tests/libqos/pci-spapr.c | 89 ++--
 tests/libqos/pci.c   | 56 --
 tests/libqos/pci.h   |  7 ++--
 4 files changed, 63 insertions(+), 176 deletions(-)

diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 51dff8a..d0eb84a 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -17,7 +17,6 @@
 #include "hw/pci/pci_regs.h"
 
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
 
 
 #define ACPI_PCIHP_ADDR 0xae00
@@ -26,14 +25,6 @@
 typedef struct QPCIBusPC
 {
 QPCIBus bus;
-
-uint32_t pci_hole_start;
-uint32_t pci_hole_size;
-uint32_t pci_hole_alloc;
-
-uint16_t pci_iohole_start;
-uint16_t pci_iohole_size;
-uint16_t pci_iohole_alloc;
 } QPCIBusPC;
 
 static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr)
@@ -132,71 +123,6 @@ static void qpci_pc_config_writel(QPCIBus *bus, int devfn, 
uint8_t offset, uint3
 outl(0xcfc, value);
 }
 
-static void *qpci_pc_iomap(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t 
*sizeptr)
-{
-QPCIBusPC *s = container_of(bus, QPCIBusPC, bus);
-static const int bar_reg_map[] = {
-PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
-PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
-};
-int bar_reg;
-uint32_t addr;
-uint64_t size;
-uint32_t io_type;
-
-g_assert(barno >= 0 && barno <= 5);
-bar_reg = bar_reg_map[barno];
-
-qpci_config_writel(dev, bar_reg, 0x);
-addr = qpci_config_readl(dev, bar_reg);
-
-io_type = addr & PCI_BASE_ADDRESS_SPACE;
-if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
-addr &= PCI_BASE_ADDRESS_IO_MASK;
-} else {
-addr &= PCI_BASE_ADDRESS_MEM_MASK;
-}
-
-size = (1ULL << ctzl(addr));
-if (size == 0) {
-return NULL;
-}
-if (sizeptr) {
-*sizeptr = size;
-}
-
-if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
-uint16_t loc;
-
-g_assert(QEMU_ALIGN_UP(s->pci_iohole_alloc, size) + size
- <= s->pci_iohole_size);
-s->pci_iohole_alloc = QEMU_ALIGN_UP(s->pci_iohole_alloc, size);
-loc = s->pci_iohole_start + s->pci_iohole_alloc;
-s->pci_iohole_alloc += size;
-
-qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
-
-return (void *)(intptr_t)loc;
-} else {
-uint64_t loc;
-
-g_assert(QEMU_ALIGN_UP(s->pci_hole_alloc, size) + size
- <= s->pci_hole_size);
-s->pci_hole_alloc = QEMU_ALIGN_UP(s->pci_hole_alloc, size);
-loc = s->pci_hole_start + s->pci_hole_alloc;
-s->pci_hole_alloc += size;
-
-qpci_config_writel(dev, bar_reg, loc);
-
-return (void *)(intptr_t)loc;
-}
-}
-
-static void qpci_pc_iounmap(QPCIBus *bus, void *data)
-{
-/* FIXME */
-}
-
 QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 {
 QPCIBusPC *ret;
@@ -227,16 +153,9 @@ QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 ret->bus.config_writew = qpci_pc_config_writew;
 ret->bus.config_writel = qpci_pc_config_writel;
 
-ret->bus.iomap = qpci_pc_iomap;
-ret->bus.iounmap = qpci_pc_iounmap;
-
-ret->pci_hole_start = 0xE000;
-ret->pci_hole_size = 0x2000;
-ret->pci_hole_alloc = 0;
-
-ret->pci_iohole_start = 0xc000;
-ret->pci_iohole_size = 0x4000;
-ret->pci_iohole_alloc = 0;
+ret->bus.pio_alloc_ptr = 0xc000;
+ret->bus.mmio_alloc_ptr = 0xE000;
+ret->bus.mmio_limit = 0x1ULL;
 
 return >bus;
 }
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index 2d26a94..70a24b5 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -34,14 +34,6 @@ typedef struct 

[Qemu-devel] [PULL 60/73] tests: Use qpci_mem{read, write} in ivshmem-test

2016-10-27 Thread David Gibson
ivshmem implements a block of shared memory in a PCI BAR.  Currently our
test case accesses this using qtest_mem{read,write}.  However, deducing
the correct addresses for these requires making assumptions about the
internel format returned by qpci_iomap(), along with some ugly casts.

This patch changes the test to use the new qpci_mem{read,write} interfaces
which is neater.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/ivshmem-test.c | 35 +++
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
index f36bfe7..fbd8258 100644
--- a/tests/ivshmem-test.c
+++ b/tests/ivshmem-test.c
@@ -93,6 +93,25 @@ static inline void out_reg(IVState *s, enum Reg reg, 
unsigned v)
 global_qtest = qtest;
 }
 
+static inline void read_mem(IVState *s, uint64_t off, void *buf, size_t len)
+{
+QTestState *qtest = global_qtest;
+
+global_qtest = s->qtest;
+qpci_memread(s->dev, s->mem_base + off, buf, len);
+global_qtest = qtest;
+}
+
+static inline void write_mem(IVState *s, uint64_t off,
+ const void *buf, size_t len)
+{
+QTestState *qtest = global_qtest;
+
+global_qtest = s->qtest;
+qpci_memwrite(s->dev, s->mem_base + off, buf, len);
+global_qtest = qtest;
+}
+
 static void cleanup_vm(IVState *s)
 {
 g_free(s->dev);
@@ -169,7 +188,7 @@ static void test_ivshmem_single(void)
 for (i = 0; i < G_N_ELEMENTS(data); i++) {
 data[i] = i;
 }
-qtest_memwrite(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data));
+write_mem(s, 0, data, sizeof(data));
 
 /* verify write */
 for (i = 0; i < G_N_ELEMENTS(data); i++) {
@@ -178,7 +197,7 @@ static void test_ivshmem_single(void)
 
 /* read it back and verify read */
 memset(data, 0, sizeof(data));
-qtest_memread(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data));
+read_mem(s, 0, data, sizeof(data));
 for (i = 0; i < G_N_ELEMENTS(data); i++) {
 g_assert_cmpuint(data[i], ==, i);
 }
@@ -201,29 +220,29 @@ static void test_ivshmem_pair(void)
 
 /* host write, guest 1 & 2 read */
 memset(tmpshmem, 0x42, TMPSHMSIZE);
-qtest_memread(s1->qtest, (uintptr_t)s1->mem_base, data, TMPSHMSIZE);
+read_mem(s1, 0, data, TMPSHMSIZE);
 for (i = 0; i < TMPSHMSIZE; i++) {
 g_assert_cmpuint(data[i], ==, 0x42);
 }
-qtest_memread(s2->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+read_mem(s2, 0, data, TMPSHMSIZE);
 for (i = 0; i < TMPSHMSIZE; i++) {
 g_assert_cmpuint(data[i], ==, 0x42);
 }
 
 /* guest 1 write, guest 2 read */
 memset(data, 0x43, TMPSHMSIZE);
-qtest_memwrite(s1->qtest, (uintptr_t)s1->mem_base, data, TMPSHMSIZE);
+write_mem(s1, 0, data, TMPSHMSIZE);
 memset(data, 0, TMPSHMSIZE);
-qtest_memread(s2->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+read_mem(s2, 0, data, TMPSHMSIZE);
 for (i = 0; i < TMPSHMSIZE; i++) {
 g_assert_cmpuint(data[i], ==, 0x43);
 }
 
 /* guest 2 write, guest 1 read */
 memset(data, 0x44, TMPSHMSIZE);
-qtest_memwrite(s2->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+write_mem(s2, 0, data, TMPSHMSIZE);
 memset(data, 0, TMPSHMSIZE);
-qtest_memread(s1->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+read_mem(s1, 0, data, TMPSHMSIZE);
 for (i = 0; i < TMPSHMSIZE; i++) {
 g_assert_cmpuint(data[i], ==, 0x44);
 }
-- 
2.7.4




[Qemu-devel] [PULL 62/73] libqos: Change PCI accessors to take opaque BAR handle

2016-10-27 Thread David Gibson
The usual use model for the libqos PCI functions is to map a specific PCI
BAR using qpci_iomap() then pass the returned token into IO accessor
functions.  This, and the fact that iomap() returns a (void *) which
actually contains a PCI space address, kind of suggests that the return
value from iomap is supposed to be an opaque token.

..except that the callers expect to be able to add offsets to it.  Which
also assumes the compiler will support pointer arithmetic on a (void *),
and treat it as working with byte offsets.

To clarify this situation change iomap() and the IO accessors to take
a definitely opaque BAR handle (enforced with a wrapper struct) along with
an offset within the BAR.  This changes both the functions and all the
callers.

There were a number of places that checked if iomap() returned non-NULL,
and or initialized it to NULL before hand.  Since iomap() already assert()s
if it fails to map the BAR, these tests were mostly pointless and are
removed.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 tests/e1000e-test.c   |   7 +-
 tests/ide-test.c  | 176 +++---
 tests/ivshmem-test.c  |  16 ++---
 tests/libqos/ahci.c   |   3 +-
 tests/libqos/ahci.h   |   6 +-
 tests/libqos/pci.c| 149 ++-
 tests/libqos/pci.h|  46 +++-
 tests/libqos/usb.c|   6 +-
 tests/libqos/usb.h|   2 +-
 tests/libqos/virtio-pci.c | 101 +-
 tests/libqos/virtio-pci.h |   2 +-
 tests/rtl8139-test.c  |  10 ++-
 tests/tco-test.c  |  80 ++---
 tests/usb-hcd-ehci-test.c |   5 +-
 14 files changed, 300 insertions(+), 309 deletions(-)

diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c
index 3979b20..8c42ca9 100644
--- a/tests/e1000e-test.c
+++ b/tests/e1000e-test.c
@@ -87,7 +87,7 @@
 
 typedef struct e1000e_device {
 QPCIDevice *pci_dev;
-void *mac_regs;
+QPCIBar mac_regs;
 
 uint64_t tx_ring;
 uint64_t rx_ring;
@@ -119,12 +119,12 @@ static QPCIDevice *e1000e_device_find(QPCIBus *bus)
 
 static void e1000e_macreg_write(e1000e_device *d, uint32_t reg, uint32_t val)
 {
-qpci_io_writel(d->pci_dev, d->mac_regs + reg, val);
+qpci_io_writel(d->pci_dev, d->mac_regs, reg, val);
 }
 
 static uint32_t e1000e_macreg_read(e1000e_device *d, uint32_t reg)
 {
-return qpci_io_readl(d->pci_dev, d->mac_regs + reg);
+return qpci_io_readl(d->pci_dev, d->mac_regs, reg);
 }
 
 static void e1000e_device_init(QPCIBus *bus, e1000e_device *d)
@@ -138,7 +138,6 @@ static void e1000e_device_init(QPCIBus *bus, e1000e_device 
*d)
 
 /* Map BAR0 (mac registers) */
 d->mac_regs = qpci_iomap(d->pci_dev, 0, NULL);
-g_assert_nonnull(d->mac_regs);
 
 /* Reset the device */
 val = e1000e_macreg_read(d, E1000E_CTRL);
diff --git a/tests/ide-test.c b/tests/ide-test.c
index 86c4373..67c7df0 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -137,7 +137,7 @@ static void ide_test_quit(void)
 qtest_end();
 }
 
-static QPCIDevice *get_pci_device(void **bmdma_base, void **ide_base)
+static QPCIDevice *get_pci_device(QPCIBar *bmdma_bar, QPCIBar *ide_bar)
 {
 QPCIDevice *dev;
 uint16_t vendor_id, device_id;
@@ -156,9 +156,9 @@ static QPCIDevice *get_pci_device(void **bmdma_base, void 
**ide_base)
 g_assert(device_id == PCI_DEVICE_ID_INTEL_82371SB_1);
 
 /* Map bmdma BAR */
-*bmdma_base = qpci_iomap(dev, 4, NULL);
+*bmdma_bar = qpci_iomap(dev, 4, NULL);
 
-*ide_base = qpci_legacy_iomap(dev, IDE_BASE);
+*ide_bar = qpci_legacy_iomap(dev, IDE_BASE);
 
 qpci_device_enable(dev);
 
@@ -181,19 +181,18 @@ typedef struct PrdtEntry {
 
 static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
 PrdtEntry *prdt, int prdt_entries,
-void(*post_exec)(QPCIDevice *dev, void *ide_base,
+void(*post_exec)(QPCIDevice *dev, QPCIBar ide_bar,
  uint64_t sector, int nb_sectors))
 {
 QPCIDevice *dev;
-void *bmdma_base;
-void *ide_base;
+QPCIBar bmdma_bar, ide_bar;
 uintptr_t guest_prdt;
 size_t len;
 bool from_dev;
 uint8_t status;
 int flags;
 
-dev = get_pci_device(_base, _base);
+dev = get_pci_device(_bar, _bar);
 
 flags = cmd & ~0xff;
 cmd &= 0xff;
@@ -218,60 +217,60 @@ static int send_dma_request(int cmd, uint64_t sector, int 
nb_sectors,
 }
 
 /* Select device 0 */
-qpci_io_writeb(dev, ide_base + reg_device, 0 | LBA);
+qpci_io_writeb(dev, ide_bar, reg_device, 0 | LBA);
 
 /* Stop any running transfer, clear any pending interrupt */
-qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);
-qpci_io_writeb(dev, bmdma_base + bmreg_status, BM_STS_INTR);
+qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
+qpci_io_writeb(dev, bmdma_bar, 

[Qemu-devel] [PULL 59/73] libqos: Add 64-bit PCI IO accessors

2016-10-27 Thread David Gibson
Currently the libqos PCI layer includes accessor helpers for 8, 16 and 32
bit reads and writes.  It's likely that we'll want 64-bit accesses in the
future (plenty of modern peripherals will have 64-bit reigsters).  This
adds them.

For PIO (not MMIO) accesses on the PC backend, this is implemented as two
32-bit ins or outs.  That's not ideal but AFAICT x86 doesn't have 64-bit
versions of in and out.

This patch also converts the single current user of 64-bit accesses -
virtio-pci.c to use the new mechanism, rather than a sequence of 8 byte
reads.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/pci-pc.c | 13 +
 tests/libqos/pci-spapr.c  | 14 ++
 tests/libqos/pci.c| 25 +
 tests/libqos/pci.h|  4 
 tests/libqos/virtio-pci.c | 16 
 5 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 849ea56..ded1c54 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -57,6 +57,17 @@ static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, 
uint32_t val)
 outl(addr, val);
 }
 
+static uint64_t qpci_pc_pio_readq(QPCIBus *bus, uint32_t addr)
+{
+return (uint64_t)inl(addr) + ((uint64_t)inl(addr + 4) << 32);
+}
+
+static void qpci_pc_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
+{
+outl(addr, val & 0x);
+outl(addr + 4, val >> 32);
+}
+
 static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
 {
 memread(addr, buf, len);
@@ -113,10 +124,12 @@ QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 ret->bus.pio_readb = qpci_pc_pio_readb;
 ret->bus.pio_readw = qpci_pc_pio_readw;
 ret->bus.pio_readl = qpci_pc_pio_readl;
+ret->bus.pio_readq = qpci_pc_pio_readq;
 
 ret->bus.pio_writeb = qpci_pc_pio_writeb;
 ret->bus.pio_writew = qpci_pc_pio_writew;
 ret->bus.pio_writel = qpci_pc_pio_writel;
+ret->bus.pio_writeq = qpci_pc_pio_writeq;
 
 ret->bus.memread = qpci_pc_memread;
 ret->bus.memwrite = qpci_pc_memwrite;
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index f26488a..1e5d015 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -78,6 +78,18 @@ static void qpci_spapr_pio_writel(QPCIBus *bus, uint32_t 
addr, uint32_t val)
 writel(s->pio_cpu_base + addr, bswap32(val));
 }
 
+static uint64_t qpci_spapr_pio_readq(QPCIBus *bus, uint32_t addr)
+{
+QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+return bswap64(readq(s->pio_cpu_base + addr));
+}
+
+static void qpci_spapr_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
+{
+QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+writeq(s->pio_cpu_base + addr, bswap64(val));
+}
+
 static void qpci_spapr_memread(QPCIBus *bus, uint32_t addr,
void *buf, size_t len)
 {
@@ -153,10 +165,12 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
 ret->bus.pio_readb = qpci_spapr_pio_readb;
 ret->bus.pio_readw = qpci_spapr_pio_readw;
 ret->bus.pio_readl = qpci_spapr_pio_readl;
+ret->bus.pio_readq = qpci_spapr_pio_readq;
 
 ret->bus.pio_writeb = qpci_spapr_pio_writeb;
 ret->bus.pio_writew = qpci_spapr_pio_writew;
 ret->bus.pio_writel = qpci_spapr_pio_writel;
+ret->bus.pio_writeq = qpci_spapr_pio_writeq;
 
 ret->bus.memread = qpci_spapr_memread;
 ret->bus.memwrite = qpci_spapr_memwrite;
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index bdffeb3..3021651 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -262,6 +262,19 @@ uint32_t qpci_io_readl(QPCIDevice *dev, void *data)
 }
 }
 
+uint64_t qpci_io_readq(QPCIDevice *dev, void *data)
+{
+uintptr_t addr = (uintptr_t)data;
+
+if (addr < QPCI_PIO_LIMIT) {
+return dev->bus->pio_readq(dev->bus, addr);
+} else {
+uint64_t val;
+dev->bus->memread(dev->bus, addr, , sizeof(val));
+return le64_to_cpu(val);
+}
+}
+
 void qpci_io_writeb(QPCIDevice *dev, void *data, uint8_t value)
 {
 uintptr_t addr = (uintptr_t)data;
@@ -297,6 +310,18 @@ void qpci_io_writel(QPCIDevice *dev, void *data, uint32_t 
value)
 }
 }
 
+void qpci_io_writeq(QPCIDevice *dev, void *data, uint64_t value)
+{
+uintptr_t addr = (uintptr_t)data;
+
+if (addr < QPCI_PIO_LIMIT) {
+dev->bus->pio_writeq(dev->bus, addr, value);
+} else {
+value = cpu_to_le64(value);
+dev->bus->memwrite(dev->bus, addr, , sizeof(value));
+}
+}
+
 void qpci_memread(QPCIDevice *dev, void *data, void *buf, size_t len)
 {
 uintptr_t addr = (uintptr_t)data;
diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index ce6ed08..531e3f7 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -26,10 +26,12 @@ struct QPCIBus {
 uint8_t (*pio_readb)(QPCIBus *bus, uint32_t addr);
 uint16_t 

[Qemu-devel] [PULL 70/73] spapr: Add DRC count indexed hotplug identifier type

2016-10-27 Thread David Gibson
From: Bharata B Rao 

Add support for DRC count indexed hotplug ID type which is primarily
needed for memory hot unplug. This type allows for specifying the
number of DRs that should be plugged/unplugged starting from a given
DRC index.

Signed-off-by: Bharata B Rao 
* updated rtas_event_log_v6_hp to reflect count/index field ordering
  used in PAPR hotplug ACR
Signed-off-by: Michael Roth 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_events.c  | 76 --
 include/hw/ppc/spapr.h |  4 +++
 2 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 9b0bd41..f85a9c3 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -175,6 +175,16 @@ struct epow_log_full {
 struct rtas_event_log_v6_epow epow;
 } QEMU_PACKED;
 
+union drc_identifier {
+uint32_t index;
+uint32_t count;
+struct {
+uint32_t count;
+uint32_t index;
+} count_indexed;
+char name[1];
+} QEMU_PACKED;
+
 struct rtas_event_log_v6_hp {
 #define RTAS_LOG_V6_SECTION_ID_HOTPLUG  0x4850 /* HP */
 struct rtas_event_log_v6_section_header hdr;
@@ -191,12 +201,9 @@ struct rtas_event_log_v6_hp {
 #define RTAS_LOG_V6_HP_ID_DRC_NAME   1
 #define RTAS_LOG_V6_HP_ID_DRC_INDEX  2
 #define RTAS_LOG_V6_HP_ID_DRC_COUNT  3
+#define RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED  4
 uint8_t reserved;
-union {
-uint32_t index;
-uint32_t count;
-char name[1];
-} drc;
+union drc_identifier drc_id;
 } QEMU_PACKED;
 
 struct hp_log_full {
@@ -488,7 +495,7 @@ static void spapr_hotplug_set_signalled(uint32_t drc_index)
 
 static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
 sPAPRDRConnectorType drc_type,
-uint32_t drc)
+union drc_identifier *drc_id)
 {
 sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 struct hp_log_full *new_hp;
@@ -533,7 +540,7 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t 
hp_action,
 case SPAPR_DR_CONNECTOR_TYPE_PCI:
 hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_PCI;
 if (hp->hotplug_action == RTAS_LOG_V6_HP_ACTION_ADD) {
-spapr_hotplug_set_signalled(drc);
+spapr_hotplug_set_signalled(drc_id->index);
 }
 break;
 case SPAPR_DR_CONNECTOR_TYPE_LMB:
@@ -551,9 +558,18 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t 
hp_action,
 }
 
 if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT) {
-hp->drc.count = cpu_to_be32(drc);
+hp->drc_id.count = cpu_to_be32(drc_id->count);
 } else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_INDEX) {
-hp->drc.index = cpu_to_be32(drc);
+hp->drc_id.index = cpu_to_be32(drc_id->index);
+} else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED) {
+/* we should not be using count_indexed value unless the guest
+ * supports dedicated hotplug event source
+ */
+g_assert(spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT));
+hp->drc_id.count_indexed.count =
+cpu_to_be32(drc_id->count_indexed.count);
+hp->drc_id.count_indexed.index =
+cpu_to_be32(drc_id->count_indexed.index);
 }
 
 rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
@@ -567,34 +583,64 @@ void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
 {
 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 sPAPRDRConnectorType drc_type = drck->get_type(drc);
-uint32_t index = drck->get_index(drc);
+union drc_identifier drc_id;
 
+drc_id.index = drck->get_index(drc);
 spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX,
-RTAS_LOG_V6_HP_ACTION_ADD, drc_type, index);
+RTAS_LOG_V6_HP_ACTION_ADD, drc_type, _id);
 }
 
 void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc)
 {
 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 sPAPRDRConnectorType drc_type = drck->get_type(drc);
-uint32_t index = drck->get_index(drc);
+union drc_identifier drc_id;
 
+drc_id.index = drck->get_index(drc);
 spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX,
-RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, index);
+RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, _id);
 }
 
 void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
uint32_t count)
 {
+union drc_identifier drc_id;
+
+drc_id.count = count;
 spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT,
-

[Qemu-devel] [PULL 49/73] spapr: improve ibm, architecture-vec-5 property handling

2016-10-27 Thread David Gibson
From: Michael Roth 

ibm,architecture-vec-5 is supposed to encode all option vector 5 bits
negotiated between platform/guest. Currently we hardcode this property
in the boot-time device tree to advertise a single negotiated
capability, "Form 1" NUMA Affinity, regardless of whether or not CAS
has been invoked or that capability has actually been negotiated.

Improve this by generating ibm,architecture-vec-5 based on the full
set of option vector 5 capabilities negotiated via CAS.

Signed-off-by: Michael Roth 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  | 23 +--
 include/hw/ppc/spapr_ovec.h |  1 +
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index aa6a070..0b3820b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -659,14 +659,28 @@ static int spapr_dt_cas_updates(sPAPRMachineState *spapr, 
void *fdt,
 sPAPROptionVector *ov5_updates)
 {
 sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
-int ret = 0;
+int ret = 0, offset;
 
 /* Generate ibm,dynamic-reconfiguration-memory node if required */
 if (spapr_ovec_test(ov5_updates, OV5_DRCONF_MEMORY)) {
 g_assert(smc->dr_lmb_enabled);
 ret = spapr_populate_drconf_memory(spapr, fdt);
+if (ret) {
+goto out;
+}
 }
 
+offset = fdt_path_offset(fdt, "/chosen");
+if (offset < 0) {
+offset = fdt_add_subnode(fdt, 0, "chosen");
+if (offset < 0) {
+return offset;
+}
+}
+ret = spapr_ovec_populate_dt(fdt, offset, spapr->ov5_cas,
+ "ibm,architecture-vec-5");
+
+out:
 return ret;
 }
 
@@ -792,14 +806,9 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void 
*fdt)
 char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
 size_t cb = 0;
 char *bootlist = get_boot_devices_list(, true);
-unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
 
 _FDT(chosen = fdt_add_subnode(fdt, 0, "chosen"));
 
-/* Set Form1_affinity */
-_FDT(fdt_setprop(fdt, chosen, "ibm,architecture-vec-5",
- vec5, sizeof(vec5)));
-
 _FDT(fdt_setprop_string(fdt, chosen, "bootargs", machine->kernel_cmdline));
 _FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
   spapr->initrd_base));
@@ -1778,6 +1787,8 @@ static void ppc_spapr_init(MachineState *machine)
 spapr_validate_node_memory(machine, _fatal);
 }
 
+spapr_ovec_set(spapr->ov5, OV5_FORM1_AFFINITY);
+
 /* init CPUs */
 if (machine->cpu_model == NULL) {
 machine->cpu_model = kvm_enabled() ? "host" : smc->tcg_default_cpu;
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index a9a3f3a..81cdd14 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -44,6 +44,7 @@ typedef struct sPAPROptionVector sPAPROptionVector;
 
 /* option vector 5 */
 #define OV5_DRCONF_MEMORY   OV_BIT(2, 2)
+#define OV5_FORM1_AFFINITY  OV_BIT(5, 0)
 
 /* interfaces */
 sPAPROptionVector *spapr_ovec_new(void);
-- 
2.7.4




[Qemu-devel] [PULL 48/73] spapr: add option vector handling in CAS-generated resets

2016-10-27 Thread David Gibson
From: Michael Roth 

In some cases, ibm,client-architecture-support calls can fail. This
could happen in the current code for situations where the modified
device tree segment exceeds the buffer size provided by the guest
via the call parameters. In these cases, QEMU will reset, allowing
an opportunity to regenerate the device tree from scratch via
boot-time handling. There are potentially other scenarios as well,
not currently reachable in the current code, but possible in theory,
such as cases where device-tree properties or nodes need to be removed.

We currently don't handle either of these properly for option vector
capabilities however. Instead of carrying the negotiated capability
beyond the reset and creating the boot-time device tree accordingly,
we start from scratch, generating the same boot-time device tree as we
did prior to the CAS-generated and the same device tree updates as we
did before. This could (in theory) cause us to get stuck in a reset
loop. This hasn't been observed, but depending on the extensiveness
of CAS-induced device tree updates in the future, could eventually
become an issue.

Address this by pulling capability-related device tree
updates resulting from CAS calls into a common routine,
spapr_dt_cas_updates(), and adding an sPAPROptionVector*
parameter that allows us to test for newly-negotiated capabilities.
We invoke it as follows:

1) When ibm,client-architecture-support gets called, we
   call spapr_dt_cas_updates() with the set of capabilities
   added since the previous call to ibm,client-architecture-support.
   For the initial boot, or a system reset generated by something
   other than the CAS call itself, this set will consist of *all*
   options supported both the platform and the guest. For calls
   to ibm,client-architecture-support immediately after a CAS-induced
   reset, we call spapr_dt_cas_updates() with only the set
   of capabilities added since the previous call, since the other
   capabilities will have already been addressed by the boot-time
   device-tree this time around. In the unlikely event that
   capabilities are *removed* since the previous CAS, we will
   generate a CAS-induced reset. In the unlikely event that we
   cannot fit the device-tree updates into the buffer provided
   by the guest, well generate a CAS-induced reset.

2) When a CAS update results in the need to reset the machine and
   include the updates in the boot-time device tree, we call the
   spapr_dt_cas_updates() using the full set of negotiated
   capabilities as part of the reset path. At initial boot, or after
   a reset generated by something other than the CAS call itself,
   this set will be empty, resulting in what should be the same
   boot-time device-tree as we generated prior to this patch. For
   CAS-induced reset, this routine will be called with the full set of
   capabilities negotiated by the platform/guest in the previous
   CAS call, which should result in CAS updates from previous call
   being accounted for in the initial boot-time device tree.

Signed-off-by: Michael Roth 
Reviewed-by: David Gibson 
[dwg: Changed an int -> bool conversion to be more explicit]
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 40 ++--
 hw/ppc/spapr_hcall.c   | 22 ++
 include/hw/ppc/spapr.h |  4 +++-
 3 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9300824..aa6a070 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -655,13 +655,28 @@ out:
 return ret;
 }
 
+static int spapr_dt_cas_updates(sPAPRMachineState *spapr, void *fdt,
+sPAPROptionVector *ov5_updates)
+{
+sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+int ret = 0;
+
+/* Generate ibm,dynamic-reconfiguration-memory node if required */
+if (spapr_ovec_test(ov5_updates, OV5_DRCONF_MEMORY)) {
+g_assert(smc->dr_lmb_enabled);
+ret = spapr_populate_drconf_memory(spapr, fdt);
+}
+
+return ret;
+}
+
 int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
  target_ulong addr, target_ulong size,
- bool cpu_update)
+ bool cpu_update,
+ sPAPROptionVector *ov5_updates)
 {
 void *fdt, *fdt_skel;
 sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
-sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine());
 
 size -= sizeof(hdr);
 
@@ -680,10 +695,8 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 _FDT((spapr_fixup_cpu_dt(fdt, spapr)));
 }
 
-/* Generate ibm,dynamic-reconfiguration-memory node if required */
-if (spapr_ovec_test(spapr->ov5_cas, OV5_DRCONF_MEMORY)) {
-g_assert(smc->dr_lmb_enabled);
-

[Qemu-devel] [PULL 51/73] libqos: Give qvirtio_config_read*() consistent semantics

2016-10-27 Thread David Gibson
The 'addr' parameter to qvirtio_config_read*() doesn't have a consistent
meaning: when using the virtio-pci versions, it's a full PCI space address,
but for virtio-mmio, it's an offset from the device's base mmio address.

This means that the callers need to do different things to calculate the
addresses in the two cases, which rather defeats the purpose of function
pointer backends.

All the current users of these functions are using them to retrieve
variables from the device specific portion of the virtio config space.
So, this patch alters the semantics to always be an offset into that
device specific config area.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/virtio-mmio.c | 16 
 tests/libqos/virtio-pci.c  | 25 ++---
 tests/virtio-9p-test.c |  8 ++--
 tests/virtio-blk-test.c| 42 +++---
 tests/virtio-scsi-test.c   |  4 +---
 5 files changed, 36 insertions(+), 59 deletions(-)

diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index bced680..7aa8383 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -15,28 +15,28 @@
 #include "libqos/malloc-generic.h"
 #include "standard-headers/linux/virtio_ring.h"
 
-static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t addr)
+static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t off)
 {
 QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
-return readb(dev->addr + addr);
+return readb(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
 }
 
-static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t addr)
+static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t off)
 {
 QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
-return readw(dev->addr + addr);
+return readw(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
 }
 
-static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t addr)
+static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t off)
 {
 QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
-return readl(dev->addr + addr);
+return readl(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
 }
 
-static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t addr)
+static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t off)
 {
 QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
-return readq(dev->addr + addr);
+return readq(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
 }
 
 static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 7e60b3a..fa82132 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -62,10 +62,13 @@ static void qvirtio_pci_assign_device(QVirtioDevice *d, 
void *data)
 *vpcidev = (QVirtioPCIDevice *)d;
 }
 
-static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t addr)
+#define CONFIG_BASE(dev) \
+((dev)->addr + VIRTIO_PCI_CONFIG_OFF((dev)->pdev->msix_enabled))
+
+static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off)
 {
 QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-return qpci_io_readb(dev->pdev, (void *)(uintptr_t)addr);
+return qpci_io_readb(dev->pdev, CONFIG_BASE(dev) + off);
 }
 
 /* PCI is always read in little-endian order
@@ -76,31 +79,31 @@ static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, 
uint64_t addr)
  * case will be managed inside qvirtio_is_big_endian()
  */
 
-static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t addr)
+static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off)
 {
 QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
 uint16_t value;
 
-value = qpci_io_readw(dev->pdev, (void *)(uintptr_t)addr);
+value = qpci_io_readw(dev->pdev, CONFIG_BASE(dev) + off);
 if (qvirtio_is_big_endian(d)) {
 value = bswap16(value);
 }
 return value;
 }
 
-static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t addr)
+static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t off)
 {
 QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
 uint32_t value;
 
-value = qpci_io_readl(dev->pdev, (void *)(uintptr_t)addr);
+value = qpci_io_readl(dev->pdev, CONFIG_BASE(dev) + off);
 if (qvirtio_is_big_endian(d)) {
 value = bswap32(value);
 }
 return value;
 }
 
-static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
+static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t off)
 {
 QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
 int i;
@@ -108,13 +111,13 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice 
*d, uint64_t addr)
 
 if (qvirtio_is_big_endian(d)) {
 for (i = 0; i < 8; ++i) {
-u64 |= (uint64_t)qpci_io_readb(dev->pdev,
-   

[Qemu-devel] [PULL 56/73] libqos: Add streaming accessors for PCI MMIO

2016-10-27 Thread David Gibson
Currently PCI memory (aka MMIO) space is accessed via a set of readb/writeb
style accessors.  This is what we want for accessing discrete registers of
a certain size.  However, there are a few cases where we instead need a
"bag of bytes" style streaming interface to PCI MMIO space.  This can be
either for streaming data style registers or when there's actual memory
rather than registers in PCI space, for example frame buffers or ivshmem.

This patch adds backend callbacks, and libqos wrappers for this type of
byte address order preserving accesses.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/pci-pc.c| 14 ++
 tests/libqos/pci-spapr.c | 17 +
 tests/libqos/pci.c   | 16 
 tests/libqos/pci.h   |  6 ++
 4 files changed, 53 insertions(+)

diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index d0eb84a..84aee25 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -87,6 +87,17 @@ static void qpci_pc_mmio_writel(QPCIBus *bus, uint32_t addr, 
uint32_t val)
 writel(addr, val);
 }
 
+static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
+{
+memread(addr, buf, len);
+}
+
+static void qpci_pc_memwrite(QPCIBus *bus, uint32_t addr,
+ const void *buf, size_t len)
+{
+memwrite(addr, buf, len);
+}
+
 static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
 {
 outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
@@ -145,6 +156,9 @@ QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 ret->bus.mmio_writew = qpci_pc_mmio_writew;
 ret->bus.mmio_writel = qpci_pc_mmio_writel;
 
+ret->bus.memread = qpci_pc_memread;
+ret->bus.memwrite = qpci_pc_memwrite;
+
 ret->bus.config_readb = qpci_pc_config_readb;
 ret->bus.config_readw = qpci_pc_config_readw;
 ret->bus.config_readl = qpci_pc_config_readl;
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index 70a24b5..ad12c2e 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -114,6 +114,20 @@ static void qpci_spapr_mmio32_writel(QPCIBus *bus, 
uint32_t addr, uint32_t val)
 writel(s->mmio32_cpu_base + addr, bswap32(val));
 }
 
+static void qpci_spapr_memread(QPCIBus *bus, uint32_t addr,
+   void *buf, size_t len)
+{
+QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+memread(s->mmio32_cpu_base + addr, buf, len);
+}
+
+static void qpci_spapr_memwrite(QPCIBus *bus, uint32_t addr,
+const void *buf, size_t len)
+{
+QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+memwrite(s->mmio32_cpu_base + addr, buf, len);
+}
+
 static uint8_t qpci_spapr_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
 {
 QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
@@ -188,6 +202,9 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
 ret->bus.mmio_writew = qpci_spapr_mmio32_writew;
 ret->bus.mmio_writel = qpci_spapr_mmio32_writel;
 
+ret->bus.memread = qpci_spapr_memread;
+ret->bus.memwrite = qpci_spapr_memwrite;
+
 ret->bus.config_readb = qpci_spapr_config_readb;
 ret->bus.config_readw = qpci_spapr_config_readw;
 ret->bus.config_readl = qpci_spapr_config_readl;
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index 98a2e56..146b063 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -289,6 +289,22 @@ void qpci_io_writel(QPCIDevice *dev, void *data, uint32_t 
value)
 }
 }
 
+void qpci_memread(QPCIDevice *dev, void *data, void *buf, size_t len)
+{
+uintptr_t addr = (uintptr_t)data;
+
+g_assert(addr >= QPCI_PIO_LIMIT);
+dev->bus->memread(dev->bus, addr, buf, len);
+}
+
+void qpci_memwrite(QPCIDevice *dev, void *data, const void *buf, size_t len)
+{
+uintptr_t addr = (uintptr_t)data;
+
+g_assert(addr >= QPCI_PIO_LIMIT);
+dev->bus->memwrite(dev->bus, addr, buf, len);
+}
+
 void *qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
 {
 QPCIBus *bus = dev->bus;
diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index b6f855e..2b08362 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -39,6 +39,9 @@ struct QPCIBus {
 void (*mmio_writew)(QPCIBus *bus, uint32_t addr, uint16_t value);
 void (*mmio_writel)(QPCIBus *bus, uint32_t addr, uint32_t value);
 
+void (*memread)(QPCIBus *bus, uint32_t addr, void *buf, size_t len);
+void (*memwrite)(QPCIBus *bus, uint32_t addr, const void *buf, size_t len);
+
 uint8_t (*config_readb)(QPCIBus *bus, int devfn, uint8_t offset);
 uint16_t (*config_readw)(QPCIBus *bus, int devfn, uint8_t offset);
 uint32_t (*config_readl)(QPCIBus *bus, int devfn, uint8_t offset);
@@ -92,6 +95,9 @@ void qpci_io_writeb(QPCIDevice *dev, void *data, uint8_t 
value);
 void qpci_io_writew(QPCIDevice *dev, void *data, uint16_t value);
 void 

[Qemu-devel] [PULL 66/73] target-ppc: Add xvcmpnesp, xvcmpnedp instructions

2016-10-27 Thread David Gibson
From: Swapnil Bokade 

xvcmpnedp[.]: VSX Vector Compare Not Equal Double-Precision
xvcmpnesp[.]: VSX Vector Compare Not Equal Single-Precision

Signed-off-by: Swapnil Bokade 
Signed-off-by: Nikunj A Dadhania 
Signed-off-by: David Gibson 
---
 target-ppc/fpu_helper.c | 19 +++
 target-ppc/helper.h |  2 ++
 target-ppc/translate/vsx-impl.inc.c |  2 ++
 target-ppc/translate/vsx-ops.inc.c  |  2 ++
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 4906372..8a389e1 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2497,8 +2497,9 @@ VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
  *   fld   - vsr_t field (VsrD(*) or VsrW(*))
  *   cmp   - comparison operation
  *   svxvc - set VXVC bit
+ *   exp   - expected result of comparison
  */
-#define VSX_CMP(op, nels, tp, fld, cmp, svxvc)\
+#define VSX_CMP(op, nels, tp, fld, cmp, svxvc, exp)   \
 void helper_##op(CPUPPCState *env, uint32_t opcode)   \
 { \
 ppc_vsr_t xt, xa, xb; \
@@ -2523,7 +2524,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)   
\
 xt.fld = 0;   \
 all_true = 0; \
 } else {  \
-if (tp##_##cmp(xb.fld, xa.fld, >fp_status) == 1) {   \
+if (tp##_##cmp(xb.fld, xa.fld, >fp_status) == exp) { \
 xt.fld = -1;  \
 all_false = 0;\
 } else {  \
@@ -2540,12 +2541,14 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) 
  \
 float_check_status(env);  \
  }
 
-VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0)
-VSX_CMP(xvcmpgedp, 2, float64, VsrD(i), le, 1)
-VSX_CMP(xvcmpgtdp, 2, float64, VsrD(i), lt, 1)
-VSX_CMP(xvcmpeqsp, 4, float32, VsrW(i), eq, 0)
-VSX_CMP(xvcmpgesp, 4, float32, VsrW(i), le, 1)
-VSX_CMP(xvcmpgtsp, 4, float32, VsrW(i), lt, 1)
+VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0, 1)
+VSX_CMP(xvcmpgedp, 2, float64, VsrD(i), le, 1, 1)
+VSX_CMP(xvcmpgtdp, 2, float64, VsrD(i), lt, 1, 1)
+VSX_CMP(xvcmpnedp, 2, float64, VsrD(i), eq, 0, 0)
+VSX_CMP(xvcmpeqsp, 4, float32, VsrW(i), eq, 0, 1)
+VSX_CMP(xvcmpgesp, 4, float32, VsrW(i), le, 1, 1)
+VSX_CMP(xvcmpgtsp, 4, float32, VsrW(i), lt, 1, 1)
+VSX_CMP(xvcmpnesp, 4, float32, VsrW(i), eq, 0, 0)
 
 /* VSX_CVT_FP_TO_FP - VSX floating point/floating point conversion
  *   op- instruction mnemonic
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 0337292..3916b2e 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -454,6 +454,7 @@ DEF_HELPER_2(xvmindp, void, env, i32)
 DEF_HELPER_2(xvcmpeqdp, void, env, i32)
 DEF_HELPER_2(xvcmpgedp, void, env, i32)
 DEF_HELPER_2(xvcmpgtdp, void, env, i32)
+DEF_HELPER_2(xvcmpnedp, void, env, i32)
 DEF_HELPER_2(xvcvdpsp, void, env, i32)
 DEF_HELPER_2(xvcvdpsxds, void, env, i32)
 DEF_HELPER_2(xvcvdpsxws, void, env, i32)
@@ -491,6 +492,7 @@ DEF_HELPER_2(xvminsp, void, env, i32)
 DEF_HELPER_2(xvcmpeqsp, void, env, i32)
 DEF_HELPER_2(xvcmpgesp, void, env, i32)
 DEF_HELPER_2(xvcmpgtsp, void, env, i32)
+DEF_HELPER_2(xvcmpnesp, void, env, i32)
 DEF_HELPER_2(xvcvspdp, void, env, i32)
 DEF_HELPER_2(xvcvspsxds, void, env, i32)
 DEF_HELPER_2(xvcvspsxws, void, env, i32)
diff --git a/target-ppc/translate/vsx-impl.inc.c 
b/target-ppc/translate/vsx-impl.inc.c
index bf167d0..5a27be4 100644
--- a/target-ppc/translate/vsx-impl.inc.c
+++ b/target-ppc/translate/vsx-impl.inc.c
@@ -685,6 +685,7 @@ GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpnedp, 0x0C, 0x0F, 0, PPC2_ISA300)
 GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
@@ -722,6 +723,7 @@ GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpnesp, 0x0C, 0x0B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
diff 

[Qemu-devel] [PULL 64/73] tests: Add pseries machine to the prom-env-test, too

2016-10-27 Thread David Gibson
Now that we also support the "-prom-env" parameter for the pseries
machine, we can enable this test for this machine, too. Since booting
with TCG is rather slow with the pseries machine, we also enable
the "-nodefaults" parameter for this test now, so that SLOF does not
have to check that much devices during boot and thus runs a little
bit faster.

Signed-off-by: Thomas Huth 
[dwg: Don't add -nodefaults to the command line, it causes extra warnings
 for the sparc testcases]
Signed-off-by: David Gibson 
---
 tests/prom-env-test.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c
index 7a62857..0ba6f48 100644
--- a/tests/prom-env-test.c
+++ b/tests/prom-env-test.c
@@ -9,11 +9,12 @@
  * This work is licensed under the terms of the GNU GPL, version 2
  * or later. See the COPYING file in the top-level directory.
  *
- * This test is used to check that some OpenBIOS machines can be started
- * successfully in TCG mode. To do this, we first put some Forth code into
- * the "boot-command" Open Firmware environment variable. This Forth code
- * writes a well-known magic value to a known location in memory. Then we
- * start the guest so that OpenBIOS can boot and finally run the Forth code.
+ * This test is used to check that some Open Firmware based machines (i.e.
+ * OpenBIOS or SLOF) can be started successfully in TCG mode. To do this, we
+ * first put some Forth code into the "boot-command" Open Firmware environment
+ * variable. This Forth code writes a well-known magic value to a known 
location
+ * in memory. Then we start the guest so that the firmware can boot and finally
+ * run the Forth code.
  * The testing code here then can finally check whether the value has been
  * successfully written into the guest memory.
  */
@@ -71,13 +72,16 @@ int main(int argc, char *argv[])
 {
 const char *sparc_machines[] = { "SPARCbook", "Voyager", "SS-20", NULL };
 const char *sparc64_machines[] = { "sun4u", "sun4v", NULL };
-const char *mac_machines[] = { "mac99", "g3beige", NULL };
+const char *ppc_machines[] = { "mac99", "g3beige", NULL };
+const char *ppc64_machines[] = { "mac99", "g3beige", "pseries", NULL };
 const char *arch = qtest_get_arch();
 
 g_test_init(, , NULL);
 
-if (!strcmp(arch, "ppc") || !strcmp(arch, "ppc64")) {
-add_tests(mac_machines);
+if (!strcmp(arch, "ppc")) {
+add_tests(ppc_machines);
+} else if (!strcmp(arch, "ppc64")) {
+add_tests(ppc64_machines);
 } else if (!strcmp(arch, "sparc")) {
 add_tests(sparc_machines);
 } else if (!strcmp(arch, "sparc64")) {
-- 
2.7.4




[Qemu-devel] [PULL 58/73] tests: Clean up IO handling in ide-test

2016-10-27 Thread David Gibson
ide-test uses many explicit inb() / outb() operations for its IO, which
means it's not portable to non-x86 platforms.  This cleans it up to use
the libqos PCI accessors instead.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 tests/ide-test.c | 179 ---
 1 file changed, 118 insertions(+), 61 deletions(-)

diff --git a/tests/ide-test.c b/tests/ide-test.c
index a8a4081..86c4373 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -137,7 +137,7 @@ static void ide_test_quit(void)
 qtest_end();
 }
 
-static QPCIDevice *get_pci_device(uint16_t *bmdma_base)
+static QPCIDevice *get_pci_device(void **bmdma_base, void **ide_base)
 {
 QPCIDevice *dev;
 uint16_t vendor_id, device_id;
@@ -156,7 +156,9 @@ static QPCIDevice *get_pci_device(uint16_t *bmdma_base)
 g_assert(device_id == PCI_DEVICE_ID_INTEL_82371SB_1);
 
 /* Map bmdma BAR */
-*bmdma_base = (uint16_t)(uintptr_t) qpci_iomap(dev, 4, NULL);
+*bmdma_base = qpci_iomap(dev, 4, NULL);
+
+*ide_base = qpci_legacy_iomap(dev, IDE_BASE);
 
 qpci_device_enable(dev);
 
@@ -179,17 +181,19 @@ typedef struct PrdtEntry {
 
 static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
 PrdtEntry *prdt, int prdt_entries,
-void(*post_exec)(uint64_t sector, int nb_sectors))
+void(*post_exec)(QPCIDevice *dev, void *ide_base,
+ uint64_t sector, int nb_sectors))
 {
 QPCIDevice *dev;
-uint16_t bmdma_base;
+void *bmdma_base;
+void *ide_base;
 uintptr_t guest_prdt;
 size_t len;
 bool from_dev;
 uint8_t status;
 int flags;
 
-dev = get_pci_device(_base);
+dev = get_pci_device(_base, _base);
 
 flags = cmd & ~0xff;
 cmd &= 0xff;
@@ -214,59 +218,60 @@ static int send_dma_request(int cmd, uint64_t sector, int 
nb_sectors,
 }
 
 /* Select device 0 */
-outb(IDE_BASE + reg_device, 0 | LBA);
+qpci_io_writeb(dev, ide_base + reg_device, 0 | LBA);
 
 /* Stop any running transfer, clear any pending interrupt */
-outb(bmdma_base + bmreg_cmd, 0);
-outb(bmdma_base + bmreg_status, BM_STS_INTR);
+qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);
+qpci_io_writeb(dev, bmdma_base + bmreg_status, BM_STS_INTR);
 
 /* Setup PRDT */
 len = sizeof(*prdt) * prdt_entries;
 guest_prdt = guest_alloc(guest_malloc, len);
 memwrite(guest_prdt, prdt, len);
-outl(bmdma_base + bmreg_prdt, guest_prdt);
+qpci_io_writel(dev, bmdma_base + bmreg_prdt, guest_prdt);
 
 /* ATA DMA command */
 if (cmd == CMD_PACKET) {
 /* Enables ATAPI DMA; otherwise PIO is attempted */
-outb(IDE_BASE + reg_feature, 0x01);
+qpci_io_writeb(dev, ide_base + reg_feature, 0x01);
 } else {
-outb(IDE_BASE + reg_nsectors, nb_sectors);
-outb(IDE_BASE + reg_lba_low,sector & 0xff);
-outb(IDE_BASE + reg_lba_middle, (sector >> 8) & 0xff);
-outb(IDE_BASE + reg_lba_high,   (sector >> 16) & 0xff);
+qpci_io_writeb(dev, ide_base + reg_nsectors, nb_sectors);
+qpci_io_writeb(dev, ide_base + reg_lba_low,sector & 0xff);
+qpci_io_writeb(dev, ide_base + reg_lba_middle, (sector >> 8) & 0xff);
+qpci_io_writeb(dev, ide_base + reg_lba_high,   (sector >> 16) & 0xff);
 }
 
-outb(IDE_BASE + reg_command, cmd);
+qpci_io_writeb(dev, ide_base + reg_command, cmd);
 
 if (post_exec) {
-post_exec(sector, nb_sectors);
+post_exec(dev, ide_base, sector, nb_sectors);
 }
 
 /* Start DMA transfer */
-outb(bmdma_base + bmreg_cmd, BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
+qpci_io_writeb(dev, bmdma_base + bmreg_cmd,
+   BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
 
 if (flags & CMDF_ABORT) {
-outb(bmdma_base + bmreg_cmd, 0);
+qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);
 }
 
 /* Wait for the DMA transfer to complete */
 do {
-status = inb(bmdma_base + bmreg_status);
+status = qpci_io_readb(dev, bmdma_base + bmreg_status);
 } while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE);
 
 g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR));
 
 /* Check IDE status code */
-assert_bit_set(inb(IDE_BASE + reg_status), DRDY);
-assert_bit_clear(inb(IDE_BASE + reg_status), BSY | DRQ);
+assert_bit_set(qpci_io_readb(dev, ide_base + reg_status), DRDY);
+assert_bit_clear(qpci_io_readb(dev, ide_base + reg_status), BSY | DRQ);
 
 /* Reading the status register clears the IRQ */
 g_assert(!get_irq(IDE_PRIMARY_IRQ));
 
 /* Stop DMA transfer if still active */
 if (status & BM_STS_ACTIVE) {
-outb(bmdma_base + bmreg_cmd, 0);
+qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);
 }
 
 free_pci_device(dev);
@@ 

[Qemu-devel] [PULL 65/73] target-ppc: add xscmp[eq, gt, ge, ne]dp instructions

2016-10-27 Thread David Gibson
From: Sandipan Das 

xscmpeqdp: VSX Scalar Compare Equal Double-Precision
xscmpgedp: VSX Scalar Compare Greater Than or Equal Double-Precision
xscmpgtdp: VSX Scalar Compare Greater Than Double-Precision
xscmpnedp: VSX Scalar Compare Not Equal Double-Precision

Signed-off-by: Sandipan Das 
Signed-off-by: Nikunj A Dadhania 
Signed-off-by: David Gibson 
---
 target-ppc/fpu_helper.c | 52 +
 target-ppc/helper.h |  4 +++
 target-ppc/translate/vsx-impl.inc.c |  4 +++
 target-ppc/translate/vsx-ops.inc.c  |  4 +++
 4 files changed, 64 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index b0760f0..4906372 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2362,6 +2362,58 @@ VSX_MADD(xvnmaddmsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 
0, 0)
 VSX_MADD(xvnmsubasp, 4, float32, VsrW(i), NMSUB_FLGS, 1, 0, 0)
 VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0, 0)
 
+/* VSX_SCALAR_CMP_DP - VSX scalar floating point compare double precision
+ *   op- instruction mnemonic
+ *   cmp   - comparison operation
+ *   exp   - expected result of comparison
+ *   svxvc - set VXVC bit
+ */
+#define VSX_SCALAR_CMP_DP(op, cmp, exp, svxvc)\
+void helper_##op(CPUPPCState *env, uint32_t opcode)   \
+{ \
+ppc_vsr_t xt, xa, xb; \
+bool vxsnan_flag = false, vxvc_flag = false, vex_flag = false;\
+  \
+getVSR(xA(opcode), , env); \
+getVSR(xB(opcode), , env); \
+getVSR(xT(opcode), , env); \
+  \
+if (float64_is_signaling_nan(xa.VsrD(0), >fp_status) ||  \
+float64_is_signaling_nan(xb.VsrD(0), >fp_status)) {  \
+vxsnan_flag = true;   \
+if (fpscr_ve == 0 && svxvc) { \
+vxvc_flag = true; \
+} \
+} else if (svxvc) {   \
+vxvc_flag = float64_is_quiet_nan(xa.VsrD(0), >fp_status) ||  \
+float64_is_quiet_nan(xb.VsrD(0), >fp_status);\
+} \
+if (vxsnan_flag) {\
+float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);\
+} \
+if (vxvc_flag) {  \
+float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0);  \
+} \
+vex_flag = fpscr_ve && (vxvc_flag || vxsnan_flag);\
+  \
+if (!vex_flag) {  \
+if (float64_##cmp(xb.VsrD(0), xa.VsrD(0), >fp_status) == exp) {  \
+xt.VsrD(0) = -1;  \
+xt.VsrD(1) = 0;   \
+} else {  \
+xt.VsrD(0) = 0;   \
+xt.VsrD(1) = 0;   \
+} \
+} \
+putVSR(xT(opcode), , env); \
+helper_float_check_status(env);   \
+}
+
+VSX_SCALAR_CMP_DP(xscmpeqdp, eq, 1, 0)
+VSX_SCALAR_CMP_DP(xscmpgedp, le, 1, 1)
+VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1)
+VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0)
+
 #define VSX_SCALAR_CMP(op, ordered)  \
 void helper_##op(CPUPPCState *env, uint32_t opcode)  \
 {\
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 5fcc546..0337292 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -389,6 +389,10 @@ 

[Qemu-devel] [PULL 71/73] spapr: use count+index for memory hotplug

2016-10-27 Thread David Gibson
From: Michael Roth 

Commit 0a417869:

spapr: Move memory hotplug to RTAS_LOG_V6_HP_ID_DRC_COUNT type

dropped per-DRC/per-LMB hotplugs event in favor of a bulk add via a
single LMB count value. This was to avoid overrunning the guest EPOW
event queue with hotplug events. This works fine, but relies on the
guest exhaustively scanning for pluggable LMBs to satisfy the
requested count by issuing rtas-get-sensor(DR_ENTITY_SENSE, ...) calls
until all the LMBs associated with the DIMM are identified.

With newer support for dedicated hotplug event source, this queue
exhaustion is no longer as much of an issue due to implementation
details on the guest side, but we still try to avoid excessive hotplug
events by now supporting both a count and a starting index to avoid
unecessary work. This patch makes use of that approach when the
capability is available.

Cc: bhar...@linux.vnet.ibm.com
Signed-off-by: Michael Roth 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index fe91883..531dfeb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2202,14 +2202,16 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error 
**errp)
 }
 }
 
-static void spapr_add_lmbs(DeviceState *dev, uint64_t addr, uint64_t size,
-   uint32_t node, Error **errp)
+static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t 
size,
+   uint32_t node, bool dedicated_hp_event_source,
+   Error **errp)
 {
 sPAPRDRConnector *drc;
 sPAPRDRConnectorClass *drck;
 uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;
 int i, fdt_offset, fdt_size;
 void *fdt;
+uint64_t addr = addr_start;
 
 for (i = 0; i < nr_lmbs; i++) {
 drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
@@ -2228,7 +2230,17 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t 
addr, uint64_t size,
  * guest only in case of hotplugged memory
  */
 if (dev->hotplugged) {
-   spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs);
+if (dedicated_hp_event_source) {
+drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
+addr_start / SPAPR_MEMORY_BLOCK_SIZE);
+drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+spapr_hotplug_req_add_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
+   nr_lmbs,
+   drck->get_index(drc));
+} else {
+spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB,
+   nr_lmbs);
+}
 }
 }
 
@@ -2261,7 +2273,9 @@ static void spapr_memory_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 goto out;
 }
 
-spapr_add_lmbs(dev, addr, size, node, _abort);
+spapr_add_lmbs(dev, addr, size, node,
+   spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT),
+   _abort);
 
 out:
 error_propagate(errp, local_err);
-- 
2.7.4




[Qemu-devel] [PULL 69/73] spapr: add hotplug interrupt machine options

2016-10-27 Thread David Gibson
From: Michael Roth 

This adds machine options of the form:

  -machine pseries,modern-hotplug-events=true
  -machine pseries,modern-hotplug-events=false

If false, QEMU will force the use of "legacy" style hotplug events,
which are surfaced through EPOW events instead of a dedicated
hot plug event source, and lack certain features necessary, mainly,
for memory unplug support.

If true, QEMU will enable support for "modern" dedicated hot plug
event source. Note that we will still default to "legacy" style unless
the guest advertises support for the "modern" hotplug events via
ibm,client-architecture-support hcall during early boot.

For pseries-2.7 and earlier we default to false, for newer machine
types we default to true.

Signed-off-by: Michael Roth 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9ddf2ff..fe91883 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2143,16 +2143,41 @@ static void spapr_set_kvm_type(Object *obj, const char 
*value, Error **errp)
 spapr->kvm_type = g_strdup(value);
 }
 
+static bool spapr_get_modern_hotplug_events(Object *obj, Error **errp)
+{
+sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+
+return spapr->use_hotplug_event_source;
+}
+
+static void spapr_set_modern_hotplug_events(Object *obj, bool value,
+Error **errp)
+{
+sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+
+spapr->use_hotplug_event_source = value;
+}
+
 static void spapr_machine_initfn(Object *obj)
 {
 sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
 
 spapr->htab_fd = -1;
+spapr->use_hotplug_event_source = true;
 object_property_add_str(obj, "kvm-type",
 spapr_get_kvm_type, spapr_set_kvm_type, NULL);
 object_property_set_description(obj, "kvm-type",
 "Specifies the KVM virtualization mode 
(HV, PR)",
 NULL);
+object_property_add_bool(obj, "modern-hotplug-events",
+spapr_get_modern_hotplug_events,
+spapr_set_modern_hotplug_events,
+NULL);
+object_property_set_description(obj, "modern-hotplug-events",
+"Use dedicated hotplug event mechanism in"
+" place of standard EPOW events when 
possible"
+" (required for memory hot-unplug 
support)",
+NULL);
 }
 
 static void spapr_machine_finalizefn(Object *obj)
@@ -2599,7 +2624,10 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, 
uint32_t index,
 
 static void spapr_machine_2_7_instance_options(MachineState *machine)
 {
+sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
+
 spapr_machine_2_8_instance_options(machine);
+spapr->use_hotplug_event_source = false;
 }
 
 static void spapr_machine_2_7_class_options(MachineClass *mc)
-- 
2.7.4




[Qemu-devel] [PULL 55/73] tests: Adjust tco-test to use qpci_legacy_iomap()

2016-10-27 Thread David Gibson
Avoid tco-test making assumptions about the internal format of the address
tokens passed to PCI IO accessors, by using the new qpci_legacy_iomap()
function.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/tco-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/tco-test.c b/tests/tco-test.c
index 0d201b1..129577d 100644
--- a/tests/tco-test.c
+++ b/tests/tco-test.c
@@ -70,7 +70,7 @@ static void test_init(TestData *d)
 /* set Root Complex BAR */
 qpci_config_writel(d->dev, ICH9_LPC_RCBA, RCBA_BASE_ADDR | 0x1);
 
-d->tco_io_base = (void *)((uintptr_t)PM_IO_BASE_ADDR + 0x60);
+d->tco_io_base = qpci_legacy_iomap(d->dev, PM_IO_BASE_ADDR + 0x60);
 }
 
 static void stop_tco(const TestData *d)
-- 
2.7.4




[Qemu-devel] [PULL 39/73] pseries: Move construction of /interrupt-controller fdt node

2016-10-27 Thread David Gibson
Currently the device tree node for the XICS interrupt controller is in
spapr_create_fdt_skel().  As part of consolidating device tree construction
to reset time, this moves it to a function called from spapr_build_fdt().

In addition we move the actual code into hw/intc/xics_spapr.c with the
rest of the PAPR specific interrupt controller code.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/intc/xics_spapr.c  | 22 ++
 hw/ppc/spapr.c| 20 +++-
 include/hw/ppc/xics.h |  1 +
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index b4e5501..2e3f1c5 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -32,6 +32,7 @@
 #include "qemu/timer.h"
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/xics.h"
+#include "hw/ppc/fdt.h"
 #include "qapi/visitor.h"
 #include "qapi/error.h"
 
@@ -449,6 +450,27 @@ void xics_spapr_free(XICSState *xics, int irq, int num)
 }
 }
 
+void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle)
+{
+uint32_t interrupt_server_ranges_prop[] = {
+0, cpu_to_be32(xics->nr_servers),
+};
+int node;
+
+_FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller"));
+
+_FDT(fdt_setprop_string(fdt, node, "device_type",
+"PowerPC-External-Interrupt-Presentation"));
+_FDT(fdt_setprop_string(fdt, node, "compatible", "IBM,ppc-xicp"));
+_FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
+_FDT(fdt_setprop(fdt, node, "ibm,interrupt-server-ranges",
+ interrupt_server_ranges_prop,
+ sizeof(interrupt_server_ranges_prop)));
+_FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
+_FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
+_FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
+}
+
 static void xics_spapr_register_types(void)
 {
 type_register_static(_spapr_info);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 17733df..102f008 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -280,7 +280,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState *spapr)
 GString *hypertas = g_string_sized_new(256);
 GString *qemu_hypertas = g_string_sized_new(256);
 uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
-uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)};
 unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
 char *buf;
 
@@ -402,22 +401,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState 
*spapr)
 
 _FDT((fdt_end_node(fdt)));
 
-/* interrupt controller */
-_FDT((fdt_begin_node(fdt, "interrupt-controller")));
-
-_FDT((fdt_property_string(fdt, "device_type",
-  "PowerPC-External-Interrupt-Presentation")));
-_FDT((fdt_property_string(fdt, "compatible", "IBM,ppc-xicp")));
-_FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
-_FDT((fdt_property(fdt, "ibm,interrupt-server-ranges",
-   interrupt_server_ranges_prop,
-   sizeof(interrupt_server_ranges_prop;
-_FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
-_FDT((fdt_property_cell(fdt, "linux,phandle", PHANDLE_XICP)));
-_FDT((fdt_property_cell(fdt, "phandle", PHANDLE_XICP)));
-
-_FDT((fdt_end_node(fdt)));
-
 /* vdevice */
 _FDT((fdt_begin_node(fdt, "vdevice")));
 
@@ -909,6 +892,9 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 /* open out the base tree into a temp buffer for the final tweaks */
 _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE)));
 
+/* /interrupt controller */
+spapr_dt_xics(spapr->xics, fdt, PHANDLE_XICP);
+
 ret = spapr_populate_memory(spapr, fdt);
 if (ret < 0) {
 error_report("couldn't setup memory nodes in fdt");
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 6e5a113..3f0c316 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -187,6 +187,7 @@ int xics_spapr_alloc(XICSState *icp, int irq_hint, bool 
lsi, Error **errp);
 int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align,
Error **errp);
 void xics_spapr_free(XICSState *icp, int irq, int num);
+void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
 void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
-- 
2.7.4




[Qemu-devel] [PULL 47/73] spapr_hcall: use spapr_ovec_* interfaces for CAS options

2016-10-27 Thread David Gibson
From: Michael Roth 

Currently we access individual bytes of an option vector via
ldub_phys() to test for the presence of a particular capability
within that byte. Currently this is only done for the "dynamic
reconfiguration memory" capability bit. If that bit is present,
we pass a boolean value to spapr_h_cas_compose_response()
to generate a modified device tree segment with the additional
properties required to enable this functionality.

As more capability bits are added, will would need to modify the
code to add additional option vector accesses and extend the
param list for spapr_h_cas_compose_response() to include similar
boolean values for these parameters.

Avoid this by switching to spapr_ovec_* helpers so we can do all
the parsing in one shot and then test for these additional bits
within spapr_h_cas_compose_response() directly.

Cc: Bharata B Rao 
Signed-off-by: Michael Roth 
Reviewed-by: David Gibson 
Reviewed-by: Bharata B Rao 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  | 10 ++--
 hw/ppc/spapr_hcall.c| 56 -
 include/hw/ppc/spapr.h  |  5 +++-
 include/hw/ppc/spapr_ovec.h |  3 +++
 4 files changed, 30 insertions(+), 44 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 209bc84..9300824 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -657,7 +657,7 @@ out:
 
 int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
  target_ulong addr, target_ulong size,
- bool cpu_update, bool memory_update)
+ bool cpu_update)
 {
 void *fdt, *fdt_skel;
 sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
@@ -681,7 +681,8 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 }
 
 /* Generate ibm,dynamic-reconfiguration-memory node if required */
-if (memory_update && smc->dr_lmb_enabled) {
+if (spapr_ovec_test(spapr->ov5_cas, OV5_DRCONF_MEMORY)) {
+g_assert(smc->dr_lmb_enabled);
 _FDT((spapr_populate_drconf_memory(spapr, fdt)));
 }
 
@@ -1740,7 +1741,12 @@ static void ppc_spapr_init(MachineState *machine)
DIV_ROUND_UP(max_cpus * smt, smp_threads),
XICS_IRQS_SPAPR, _fatal);
 
+/* Set up containers for ibm,client-set-architecture negotiated options */
+spapr->ov5 = spapr_ovec_new();
+spapr->ov5_cas = spapr_ovec_new();
+
 if (smc->dr_lmb_enabled) {
+spapr_ovec_set(spapr->ov5, OV5_DRCONF_MEMORY);
 spapr_validate_node_memory(machine, _fatal);
 }
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index c5e7e8c..f1d081b 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -11,6 +11,7 @@
 #include "trace.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
+#include "hw/ppc/spapr_ovec.h"
 
 struct SPRSyncState {
 int spr;
@@ -880,32 +881,6 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 return ret;
 }
 
-/*
- * Return the offset to the requested option vector @vector in the
- * option vector table @table.
- */
-static target_ulong cas_get_option_vector(int vector, target_ulong table)
-{
-int i;
-char nr_vectors, nr_entries;
-
-if (!table) {
-return 0;
-}
-
-nr_vectors = (ldl_phys(_space_memory, table) >> 24) + 1;
-if (!vector || vector > nr_vectors) {
-return 0;
-}
-table++; /* skip nr option vectors */
-
-for (i = 0; i < vector - 1; i++) {
-nr_entries = ldl_phys(_space_memory, table) >> 24;
-table += nr_entries + 2;
-}
-return table;
-}
-
 typedef struct {
 uint32_t cpu_version;
 Error *err;
@@ -961,23 +936,21 @@ static void cas_handle_compat_cpu(PowerPCCPUClass *pcc, 
uint32_t pvr,
 }
 }
 
-#define OV5_DRCONF_MEMORY 0x20
-
 static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
   sPAPRMachineState *spapr,
   target_ulong opcode,
   target_ulong *args)
 {
 target_ulong list = ppc64_phys_to_real(args[0]);
-target_ulong ov_table, ov5;
+target_ulong ov_table;
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu_);
 CPUState *cs;
-bool cpu_match = false, cpu_update = true, memory_update = false;
+bool cpu_match = false, cpu_update = true;
 unsigned old_cpu_version = cpu_->cpu_version;
 unsigned compat_lvl = 0, cpu_version = 0;
 unsigned max_lvl = get_compat_level(cpu_->max_compat);
 int counter;
-char ov5_byte2;
+sPAPROptionVector *ov5_guest;
 
 /* Parse PVR list */
 for (counter = 0; counter < 512; ++counter) {
@@ -1033,19 +1006,20 @@ static target_ulong 

[Qemu-devel] [PULL 45/73] pseries: Remove spapr_create_fdt_skel()

2016-10-27 Thread David Gibson
For historical reasons construction of the guest device tree in spapr is
divided between spapr_create_fdt_skel() which is called at init time, and
spapr_build_fdt() which runs at reset time.  Over time, more and more
things have needed to be moved to reset time.

Previous cleanups mean the only things left in spapr_create_fdt_skel() are
the properties of the root node itself.  Finish consolidating these two
parts of device tree construction, by moving this to the start of
spapr_build_fdt(), and removing spapr_create_fdt_skel() entirely.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 94 +++---
 include/hw/ppc/spapr.h |  1 -
 2 files changed, 36 insertions(+), 59 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 34846da..209bc84 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -271,57 +271,6 @@ static void add_str(GString *s, const gchar *s1)
 g_string_append_len(s, s1, strlen(s1) + 1);
 }
 
-static void *spapr_create_fdt_skel(sPAPRMachineState *spapr)
-{
-void *fdt;
-char *buf;
-
-fdt = g_malloc0(FDT_MAX_SIZE);
-_FDT((fdt_create(fdt, FDT_MAX_SIZE)));
-
-_FDT((fdt_finish_reservemap(fdt)));
-
-/* Root node */
-_FDT((fdt_begin_node(fdt, "")));
-_FDT((fdt_property_string(fdt, "device_type", "chrp")));
-_FDT((fdt_property_string(fdt, "model", "IBM pSeries (emulated by 
qemu)")));
-_FDT((fdt_property_string(fdt, "compatible", "qemu,pseries")));
-
-/*
- * Add info to guest to indentify which host is it being run on
- * and what is the uuid of the guest
- */
-if (kvmppc_get_host_model()) {
-_FDT((fdt_property_string(fdt, "host-model", buf)));
-g_free(buf);
-}
-if (kvmppc_get_host_serial()) {
-_FDT((fdt_property_string(fdt, "host-serial", buf)));
-g_free(buf);
-}
-
-buf = qemu_uuid_unparse_strdup(_uuid);
-
-_FDT((fdt_property_string(fdt, "vm,uuid", buf)));
-if (qemu_uuid_set) {
-_FDT((fdt_property_string(fdt, "system-id", buf)));
-}
-g_free(buf);
-
-if (qemu_get_vm_name()) {
-_FDT((fdt_property_string(fdt, "ibm,partition-name",
-  qemu_get_vm_name(;
-}
-
-_FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
-_FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
-
-_FDT((fdt_end_node(fdt))); /* close root node */
-_FDT((fdt_finish(fdt)));
-
-return fdt;
-}
-
 static int spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start,
hwaddr size)
 {
@@ -916,11 +865,44 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 int ret;
 void *fdt;
 sPAPRPHBState *phb;
+char *buf;
 
-fdt = g_malloc(FDT_MAX_SIZE);
+fdt = g_malloc0(FDT_MAX_SIZE);
+_FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
 
-/* open out the base tree into a temp buffer for the final tweaks */
-_FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE)));
+/* Root node */
+_FDT(fdt_setprop_string(fdt, 0, "device_type", "chrp"));
+_FDT(fdt_setprop_string(fdt, 0, "model", "IBM pSeries (emulated by 
qemu)"));
+_FDT(fdt_setprop_string(fdt, 0, "compatible", "qemu,pseries"));
+
+/*
+ * Add info to guest to indentify which host is it being run on
+ * and what is the uuid of the guest
+ */
+if (kvmppc_get_host_model()) {
+_FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
+g_free(buf);
+}
+if (kvmppc_get_host_serial()) {
+_FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
+g_free(buf);
+}
+
+buf = qemu_uuid_unparse_strdup(_uuid);
+
+_FDT(fdt_setprop_string(fdt, 0, "vm,uuid", buf));
+if (qemu_uuid_set) {
+_FDT(fdt_setprop_string(fdt, 0, "system-id", buf));
+}
+g_free(buf);
+
+if (qemu_get_vm_name()) {
+_FDT(fdt_setprop_string(fdt, 0, "ibm,partition-name",
+qemu_get_vm_name()));
+}
+
+_FDT(fdt_setprop_cell(fdt, 0, "#address-cells", 2));
+_FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
 /* /interrupt controller */
 spapr_dt_xics(spapr->xics, fdt, PHANDLE_XICP);
@@ -2014,10 +1996,6 @@ static void ppc_spapr_init(MachineState *machine)
 register_savevm_live(NULL, "spapr/htab", -1, 1,
  _htab_handlers, spapr);
 
-/* Prepare the device tree */
-spapr->fdt_skel = spapr_create_fdt_skel(spapr);
-assert(spapr->fdt_skel != NULL);
-
 /* used by RTAS */
 QTAILQ_INIT(>ccs_list);
 qemu_register_reset(spapr_ccs_reset_hook, spapr);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index ae7d1d7..d5d6e57 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -69,7 +69,6 @@ struct sPAPRMachineState {
 bool kernel_le;
 uint32_t initrd_base;
   

[Qemu-devel] [PULL 37/73] pseries: Move adding of fdt reserve map entries

2016-10-27 Thread David Gibson
The flattened device tree passed to pseries guests contains a list of
reserved memory areas.  Currently we construct this list early in
spapr_create_fdt_skel() as we sequentially write the fdt.

This will be inconvenient for upcoming cleanups, so this patch moves
the reserve map changes to the end of fdt construction.  This changes
fdt_add_reservemap_entry() calls - which work when writing the fdt
sequentially to fdt_add_mem_rsv() calls used when altering the fdt in
random access mode.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3b23920..8e58d86 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -301,14 +301,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState 
*spapr)
 fdt = g_malloc0(FDT_MAX_SIZE);
 _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
 
-if (spapr->kernel_size) {
-_FDT((fdt_add_reservemap_entry(fdt, KERNEL_LOAD_ADDR,
-   spapr->kernel_size)));
-}
-if (spapr->initrd_size) {
-_FDT((fdt_add_reservemap_entry(fdt, spapr->initrd_base,
-   spapr->initrd_size)));
-}
 _FDT((fdt_finish_reservemap(fdt)));
 
 /* Root node */
@@ -997,6 +989,15 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 }
 
 g_free(bootlist);
+
+/* Build memory reserve map */
+if (spapr->kernel_size) {
+_FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size)));
+}
+if (spapr->initrd_size) {
+_FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, spapr->initrd_size)));
+}
+
 return fdt;
 }
 
-- 
2.7.4




[Qemu-devel] [PULL 52/73] libqos: Handle PCI IO de-multiplexing in common code

2016-10-27 Thread David Gibson
The PCI IO space (aka PIO, aka legacy IO) and PCI memory space (aka MMIO)
are distinct address spaces by the PCI spec (although parts of one might be
aliased to parts of the other in some cases).

However, qpci_io_read*() and qpci_io_write*() can perform accesses to
either space depending on parameter.  That's convenient for test case
drivers, since there are a fair few devices which can be controlled via
either a PIO or MMIO BAR but with an otherwise identical driver.

This is implemented by having addresses below 64kiB treated as PIO, and
those above treated as MMIO.  This works because low addresses in memory
space are generally reserved for DMA rather than MMIO.

At the moment, this demultiplexing must be handled by each PCI backend
(pc and spapr, so far).  There's no real reason for this - the current
encoding is likely to work for all platforms, and even if it doesn't we
can still use a more complex common encoding since the value returned from
iomap are semi-opaque.

This patch moves the demultiplexing into the common part of the libqos PCI
code, with the backends having simpler, separate accessors for PIO and
MMIO space.  This also means we have a way of explicitly accessing either
space if it's necessary for some special case.

Signed-off-by: David Gibson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
---
 tests/libqos/pci-pc.c| 107 --
 tests/libqos/pci-spapr.c | 118 +--
 tests/libqos/pci.c   |  49 +---
 tests/libqos/pci.h   |  22 ++---
 4 files changed, 170 insertions(+), 126 deletions(-)

diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 9600ed6..51dff8a 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -36,79 +36,64 @@ typedef struct QPCIBusPC
 uint16_t pci_iohole_alloc;
 } QPCIBusPC;
 
-static uint8_t qpci_pc_io_readb(QPCIBus *bus, void *addr)
+static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr)
 {
-uintptr_t port = (uintptr_t)addr;
-uint8_t value;
-
-if (port < 0x1) {
-value = inb(port);
-} else {
-value = readb(port);
-}
-
-return value;
+return inb(addr);
 }
 
-static uint16_t qpci_pc_io_readw(QPCIBus *bus, void *addr)
+static uint8_t qpci_pc_mmio_readb(QPCIBus *bus, uint32_t addr)
 {
-uintptr_t port = (uintptr_t)addr;
-uint16_t value;
-
-if (port < 0x1) {
-value = inw(port);
-} else {
-value = readw(port);
-}
+return readb(addr);
+}
 
-return value;
+static void qpci_pc_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
+{
+outb(addr, val);
 }
 
-static uint32_t qpci_pc_io_readl(QPCIBus *bus, void *addr)
+static void qpci_pc_mmio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
 {
-uintptr_t port = (uintptr_t)addr;
-uint32_t value;
+writeb(addr, val);
+}
 
-if (port < 0x1) {
-value = inl(port);
-} else {
-value = readl(port);
-}
+static uint16_t qpci_pc_pio_readw(QPCIBus *bus, uint32_t addr)
+{
+return inw(addr);
+}
 
-return value;
+static uint16_t qpci_pc_mmio_readw(QPCIBus *bus, uint32_t addr)
+{
+return readw(addr);
 }
 
-static void qpci_pc_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
+static void qpci_pc_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
 {
-uintptr_t port = (uintptr_t)addr;
+outw(addr, val);
+}
 
-if (port < 0x1) {
-outb(port, value);
-} else {
-writeb(port, value);
-}
+static void qpci_pc_mmio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
+{
+writew(addr, val);
 }
 
-static void qpci_pc_io_writew(QPCIBus *bus, void *addr, uint16_t value)
+static uint32_t qpci_pc_pio_readl(QPCIBus *bus, uint32_t addr)
 {
-uintptr_t port = (uintptr_t)addr;
+return inl(addr);
+}
 
-if (port < 0x1) {
-outw(port, value);
-} else {
-writew(port, value);
-}
+static uint32_t qpci_pc_mmio_readl(QPCIBus *bus, uint32_t addr)
+{
+return readl(addr);
 }
 
-static void qpci_pc_io_writel(QPCIBus *bus, void *addr, uint32_t value)
+static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
 {
-uintptr_t port = (uintptr_t)addr;
+outl(addr, val);
+}
 
-if (port < 0x1) {
-outl(port, value);
-} else {
-writel(port, value);
-}
+static void qpci_pc_mmio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
+{
+writel(addr, val);
 }
 
 static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
@@ -218,13 +203,21 @@ QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 
 ret = g_malloc(sizeof(*ret));
 
-ret->bus.io_readb = qpci_pc_io_readb;
-ret->bus.io_readw = qpci_pc_io_readw;
-ret->bus.io_readl = qpci_pc_io_readl;
+ret->bus.pio_readb = qpci_pc_pio_readb;
+ret->bus.pio_readw = qpci_pc_pio_readw;
+ret->bus.pio_readl = 

[Qemu-devel] [PULL 32/73] ppc/pnv: add a ISA bus

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

As Qemu only supports a single instance of the ISA bus, we use the LPC
controller of chip 0 to create one and plug in a couple of useful
devices, like an UART and RTC. An IPMI BT device, which is also an ISA
device, can be defined on the command line to connect an external BMC.
That is for later.

The PowerNV machine now has a console. Skiboot should load a kernel
and jump into it but execution will stop quite early because we lack a
model for the native XICS controller for the moment :

[0.00] NR_IRQS:512 nr_irqs:512 16
[0.00] XICS: Cannot find a Presentation Controller !
[0.00] [ cut here ]
[0.00] WARNING: at arch/powerpc/platforms/powernv/setup.c:81
...
[0.00] NIP [c079d65c] pnv_init_IRQ+0x30/0x44

You can still do a few things under xmon.

Based on previous work from :
  Benjamin Herrenschmidt 

Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
[dwg: Trivial fix for a change in the serial_hds_isa_init() interface]
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 65 
 include/hw/ppc/pnv.h |  2 ++
 2 files changed, 67 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index aa712fd..82276e0 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -35,6 +35,10 @@
 
 #include "hw/ppc/pnv_xscom.h"
 
+#include "hw/isa/isa.h"
+#include "hw/char/serial.h"
+#include "hw/timer/mc146818rtc.h"
+
 #include 
 
 #define FDT_MAX_SIZE0x0010
@@ -301,6 +305,58 @@ static void ppc_powernv_reset(void)
 cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
 }
 
+/* If we don't use the built-in LPC interrupt deserializer, we need
+ * to provide a set of qirqs for the ISA bus or things will go bad.
+ *
+ * Most machines using pre-Naples chips (without said deserializer)
+ * have a CPLD that will collect the SerIRQ and shoot them as a
+ * single level interrupt to the P8 chip. So let's setup a hook
+ * for doing just that.
+ *
+ * Note: The actual interrupt input isn't emulated yet, this will
+ * come with the PSI bridge model.
+ */
+static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
+{
+/* We don't yet emulate the PSI bridge which provides the external
+ * interrupt, so just drop interrupts on the floor
+ */
+}
+
+static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
+{
+ /* XXX TODO */
+}
+
+static ISABus *pnv_isa_create(PnvChip *chip)
+{
+PnvLpcController *lpc = >lpc;
+ISABus *isa_bus;
+qemu_irq *irqs;
+PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+
+/* let isa_bus_new() create its own bridge on SysBus otherwise
+ * devices speficied on the command line won't find the bus and
+ * will fail to create.
+ */
+isa_bus = isa_bus_new(NULL, >isa_mem, >isa_io,
+  _fatal);
+
+/* Not all variants have a working serial irq decoder. If not,
+ * handling of LPC interrupts becomes a platform issue (some
+ * platforms have a CPLD to do it).
+ */
+if (pcc->chip_type == PNV_CHIP_POWER8NVL) {
+irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler, chip, ISA_NUM_IRQS);
+} else {
+irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, chip,
+  ISA_NUM_IRQS);
+}
+
+isa_bus_irqs(isa_bus, irqs);
+return isa_bus;
+}
+
 static void ppc_powernv_init(MachineState *machine)
 {
 PnvMachineState *pnv = POWERNV_MACHINE(machine);
@@ -395,6 +451,15 @@ static void ppc_powernv_init(MachineState *machine)
 object_property_set_bool(chip, true, "realized", _fatal);
 }
 g_free(chip_typename);
+
+/* Instantiate ISA bus on chip 0 */
+pnv->isa_bus = pnv_isa_create(pnv->chips[0]);
+
+/* Create serial port */
+serial_hds_isa_init(pnv->isa_bus, 0, MAX_SERIAL_PORTS);
+
+/* Create an RTC ISA device too */
+rtc_init(pnv->isa_bus, 2000, NULL);
 }
 
 /*
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index ce16e47..02ac1c5 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -112,6 +112,8 @@ typedef struct PnvMachineState {
 
 uint32_t num_chips;
 PnvChip  **chips;
+
+ISABus   *isa_bus;
 } PnvMachineState;
 
 #define PNV_FDT_ADDR  0x0100
-- 
2.7.4




[Qemu-devel] [PULL 30/73] ppc/pnv: add XSCOM handlers to PnvCore

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

Now that we are using real HW ids for the cores in PowerNV chips, we
can route the XSCOM accesses to them. We just need to attach a
specific XSCOM memory region to each core in the appropriate window
for the core number.

To start with, let's install the DTS (Digital Thermal Sensor) handlers
which should return 38°C for each core.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c   |  4 
 hw/ppc/pnv_core.c  | 50 ++
 include/hw/ppc/pnv_core.h  |  2 ++
 include/hw/ppc/pnv_xscom.h | 19 ++
 4 files changed, 75 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 96ba36c..df55a89 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -625,6 +625,10 @@ static void pnv_chip_realize(DeviceState *dev, Error 
**errp)
 object_property_set_bool(OBJECT(pnv_core), true, "realized",
  _fatal);
 object_unref(OBJECT(pnv_core));
+
+/* Each core has an XSCOM MMIO region */
+pnv_xscom_add_subregion(chip, PNV_XSCOM_EX_CORE_BASE(core_hwid),
+_CORE(pnv_core)->xscom_regs);
 i++;
 }
 g_free(typename);
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 04713ca..2acda96 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -19,6 +19,7 @@
 #include "qemu/osdep.h"
 #include "sysemu/sysemu.h"
 #include "qapi/error.h"
+#include "qemu/log.h"
 #include "target-ppc/cpu.h"
 #include "hw/ppc/ppc.h"
 #include "hw/ppc/pnv.h"
@@ -63,6 +64,51 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp)
 qemu_register_reset(powernv_cpu_reset, cpu);
 }
 
+/*
+ * These values are read by the PowerNV HW monitors under Linux
+ */
+#define PNV_XSCOM_EX_DTS_RESULT0 0x5
+#define PNV_XSCOM_EX_DTS_RESULT1 0x50001
+
+static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
+unsigned int width)
+{
+uint32_t offset = addr >> 3;
+uint64_t val = 0;
+
+/* The result should be 38 C */
+switch (offset) {
+case PNV_XSCOM_EX_DTS_RESULT0:
+val = 0x26f024f023full;
+break;
+case PNV_XSCOM_EX_DTS_RESULT1:
+val = 0x24full;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx,
+  addr);
+}
+
+return val;
+}
+
+static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int width)
+{
+qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx,
+  addr);
+}
+
+static const MemoryRegionOps pnv_core_xscom_ops = {
+.read = pnv_core_xscom_read,
+.write = pnv_core_xscom_write,
+.valid.min_access_size = 8,
+.valid.max_access_size = 8,
+.impl.min_access_size = 8,
+.impl.max_access_size = 8,
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
 static void pnv_core_realize_child(Object *child, Error **errp)
 {
 Error *local_err = NULL;
@@ -118,6 +164,10 @@ static void pnv_core_realize(DeviceState *dev, Error 
**errp)
 goto err;
 }
 }
+
+snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
+pnv_xscom_region_init(>xscom_regs, OBJECT(dev), _core_xscom_ops,
+  pc, name, PNV_XSCOM_EX_CORE_SIZE);
 return;
 
 err:
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index a151e28..2955a41 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -36,6 +36,8 @@ typedef struct PnvCore {
 /*< public >*/
 void *threads;
 uint32_t pir;
+
+MemoryRegion xscom_regs;
 } PnvCore;
 
 typedef struct PnvCoreClass {
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index ee25ec4..5da6e92 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -41,6 +41,25 @@ typedef struct PnvXScomInterfaceClass {
 int (*populate)(PnvXScomInterface *dev, void *fdt, int offset);
 } PnvXScomInterfaceClass;
 
+/*
+ * Layout of the XSCOM PCB addresses of EX core 1
+ *
+ *   GPIO0x1100
+ *   SCOM0x1101
+ *   OHA 0x1102
+ *   CLOCK CTL   0x1103
+ *   FIR 0x1104
+ *   THERM   0x1105
+ * 0x1106
+ *   ..
+ *   0x110E
+ *   PCB SLAVE   0x110F
+ */
+
+#define PNV_XSCOM_EX_BASE 0x1000
+#define PNV_XSCOM_EX_CORE_BASE(i) (PNV_XSCOM_EX_BASE | (((uint64_t)i) << 24))
+#define PNV_XSCOM_EX_CORE_SIZE0x10
+
 extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
 extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset);
 
-- 
2.7.4




[Qemu-devel] [PULL 29/73] ppc/pnv: add XSCOM infrastructure

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

On a real POWER8 system, the Pervasive Interconnect Bus (PIB) serves
as a backbone to connect different units of the system. The host
firmware connects to the PIB through a bridge unit, the
Alter-Display-Unit (ADU), which gives him access to all the chiplets
on the PCB network (Pervasive Connect Bus), the PIB acting as the root
of this network.

XSCOM (serial communication) is the interface to the sideband bus
provided by the POWER8 pervasive unit to read and write to chiplets
resources. This is needed by the host firmware, OPAL and to a lesser
extent, Linux. This is among others how the PCI Host bridges get
configured at boot or how the LPC bus is accessed.

To represent the ADU of a real system, we introduce a specific
AddressSpace to dispatch XSCOM accesses to the targeted chiplets. The
translation of an XSCOM address into a PCB register address is
slightly different between the P9 and the P8. This is handled before
the dispatch using a 8byte alignment for all.

To customize the device tree, a QOM InterfaceClass, PnvXScomInterface,
is provided with a populate() handler. The chip populates the device
tree by simply looping on its children. Therefore, each model needing
custom nodes should not forget to declare itself as a child at
instantiation time.

Based on previous work done by :
  Benjamin Herrenschmidt 

Signed-off-by: Cédric Le Goater 
[dwg: Added cpu parameter to xscom_complete()]
Signed-off-by: David Gibson 
---
 hw/ppc/Makefile.objs   |   2 +-
 hw/ppc/pnv.c   |  25 +
 hw/ppc/pnv_xscom.c | 275 +
 include/hw/ppc/pnv.h   |  15 +++
 include/hw/ppc/pnv_xscom.h |  56 +
 5 files changed, 372 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/pnv_xscom.c
 create mode 100644 include/hw/ppc/pnv_xscom.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index f8c7d1d..08c213c 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o 
spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
 # IBM PowerNV
-obj-$(CONFIG_POWERNV) += pnv.o pnv_core.o
+obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 3413107..96ba36c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -33,6 +33,8 @@
 #include "qemu/cutils.h"
 #include "qapi/visitor.h"
 
+#include "hw/ppc/pnv_xscom.h"
+
 #include 
 
 #define FDT_MAX_SIZE0x0010
@@ -219,6 +221,8 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt)
 size_t typesize = object_type_get_instance_size(typename);
 int i;
 
+pnv_xscom_populate(chip, fdt, 0);
+
 for (i = 0; i < chip->nr_cores; i++) {
 PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
 
@@ -455,6 +459,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, 
void *data)
 k->chip_cfam_id = 0x221ef0498000ull;  /* P8 Murano DD2.1 */
 k->cores_mask = POWER8E_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p8;
+k->xscom_base = 0x003fc00ull;
 dc->desc = "PowerNV Chip POWER8E";
 }
 
@@ -475,6 +480,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, 
void *data)
 k->chip_cfam_id = 0x220ea0498000ull; /* P8 Venice DD2.0 */
 k->cores_mask = POWER8_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p8;
+k->xscom_base = 0x003fc00ull;
 dc->desc = "PowerNV Chip POWER8";
 }
 
@@ -495,6 +501,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 k->chip_cfam_id = 0x120d30498000ull;  /* P8 Naples DD1.0 */
 k->cores_mask = POWER8_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p8;
+k->xscom_base = 0x003fc00ull;
 dc->desc = "PowerNV Chip POWER8NVL";
 }
 
@@ -515,6 +522,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, 
void *data)
 k->chip_cfam_id = 0x100d10498000ull; /* P9 Nimbus DD1.0 */
 k->cores_mask = POWER9_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p9;
+k->xscom_base = 0x00603fcull;
 dc->desc = "PowerNV Chip POWER9";
 }
 
@@ -555,6 +563,14 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error 
**errp)
 }
 }
 
+static void pnv_chip_init(Object *obj)
+{
+PnvChip *chip = PNV_CHIP(obj);
+PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+
+chip->xscom_base = pcc->xscom_base;
+}
+
 static void pnv_chip_realize(DeviceState *dev, Error **errp)
 {
 PnvChip *chip = PNV_CHIP(dev);
@@ -569,6 +585,14 @@ static void pnv_chip_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+/* XSCOM bridge */
+pnv_xscom_realize(chip, );
+if (error) {
+error_propagate(errp, error);
+

[Qemu-devel] [PULL 42/73] pseries: Move /event-sources construction to spapr_build_fdt()

2016-10-27 Thread David Gibson
The /event-sources device tree node is built from spapr_create_fdt_skel().
As part of consolidating device tree construction to reset time, this moves
it to spapr_build_fdt().

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c |  6 +++---
 hw/ppc/spapr_events.c  | 21 ++---
 include/hw/ppc/spapr.h |  2 +-
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1b61de2..048fb3d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -328,9 +328,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState *spapr)
 
 _FDT((fdt_end_node(fdt)));
 
-/* event-sources */
-spapr_events_fdt_skel(fdt, spapr->check_exception_irq);
-
 /* /hypervisor node */
 if (kvm_enabled()) {
 uint8_t hypercall[16];
@@ -983,6 +980,9 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 }
 }
 
+/* /event-sources */
+spapr_dt_events(fdt, spapr->check_exception_irq);
+
 /* /rtas */
 spapr_dt_rtas(spapr, fdt);
 
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 6d35345..89aa5a7 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -211,23 +211,22 @@ struct hp_log_full {
 #define EVENT_MASK_HOTPLUG   0x1000
 #define EVENT_MASK_IO0x0800
 
-void spapr_events_fdt_skel(void *fdt, uint32_t check_exception_irq)
+void spapr_dt_events(void *fdt, uint32_t check_exception_irq)
 {
+int event_sources, epow_events;
 uint32_t irq_ranges[] = {cpu_to_be32(check_exception_irq), cpu_to_be32(1)};
 uint32_t interrupts[] = {cpu_to_be32(check_exception_irq), 0};
 
-_FDT((fdt_begin_node(fdt, "event-sources")));
+_FDT(event_sources = fdt_add_subnode(fdt, 0, "event-sources"));
 
-_FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
-_FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
-_FDT((fdt_property(fdt, "interrupt-ranges",
-   irq_ranges, sizeof(irq_ranges;
+_FDT(fdt_setprop(fdt, event_sources, "interrupt-controller", NULL, 0));
+_FDT(fdt_setprop_cell(fdt, event_sources, "#interrupt-cells", 2));
+_FDT(fdt_setprop(fdt, event_sources, "interrupt-ranges",
+ irq_ranges, sizeof(irq_ranges)));
 
-_FDT((fdt_begin_node(fdt, "epow-events")));
-_FDT((fdt_property(fdt, "interrupts", interrupts, sizeof(interrupts;
-_FDT((fdt_end_node(fdt)));
-
-_FDT((fdt_end_node(fdt)));
+_FDT(epow_events = fdt_add_subnode(fdt, event_sources, "epow-events"));
+_FDT(fdt_setprop(fdt, epow_events, "interrupts",
+ interrupts, sizeof(interrupts)));
 }
 
 static void rtas_event_log_queue(int log_type, void *data, bool exception)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 8b8bb97..ae7d1d7 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -581,7 +581,7 @@ struct sPAPREventLogEntry {
 };
 
 void spapr_events_init(sPAPRMachineState *sm);
-void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
+void spapr_dt_events(void *fdt, uint32_t check_exception_irq);
 int spapr_h_cas_compose_response(sPAPRMachineState *sm,
  target_ulong addr, target_ulong size,
  bool cpu_update, bool memory_update);
-- 
2.7.4




[Qemu-devel] [PULL 31/73] ppc/pnv: add a LPC controller

2016-10-27 Thread David Gibson
From: Benjamin Herrenschmidt 

The LPC (Low Pin Count) interface on a POWER8 is made accessible to
the system through the ADU (XSCOM interface). This interface is part
of set of units connected together via a local OPB (On-Chip Peripheral
Bus) which act as a bridge between the ADU and the off chip LPC
endpoints, like external flash modules.

The most important units of this OPB are :
 - OPB Master: contains the ADU slave logic, a set of internal
   registers and the logic to control the OPB.
 - LPCHC (LPC HOST Controller): which implements a OPB Slave, a set of
   internal registers and the LPC HOST Controller to control the LPC
   interface.

Four address spaces are provided to the ADU :
 - LPC Bus Firmware Memory
 - LPC Bus Memory
 - LPC Bus I/O (ISA bus)
 - and the registers for the OPB Master and the LPC Host Controller

On POWER8, an intermediate hop is necessary to reach the OPB, through
a unit called the ECCB. OPB commands are simply mangled in ECCB write
commands.

On POWER9, the OPB master address space can be accessed via MMIO. The
logic is same but the code will be simpler as the XSCOM and ECCB hops
are not necessary anymore.

This version of the LPC controller model doesn't yet implement support
for the SerIRQ deserializer present in the Naples version of the chip
though some preliminary work is there.

Signed-off-by: Benjamin Herrenschmidt 
[clg: - updated for qemu-2.7
  - ported on latest PowerNV patchset
  - changed the XSCOM interface to fit new model
  - QOMified the model
  - moved the ISA hunks in another patch
  - removed printf logging
  - added a couple of UNIMP logging
  - rewrote commit log ]
Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/Makefile.objs   |   2 +-
 hw/ppc/pnv.c   |   8 +
 hw/ppc/pnv_lpc.c   | 471 +
 include/hw/ppc/pnv.h   |   3 +
 include/hw/ppc/pnv_lpc.h   |  67 +++
 include/hw/ppc/pnv_xscom.h |   3 +
 6 files changed, 553 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/pnv_lpc.c
 create mode 100644 include/hw/ppc/pnv_lpc.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 08c213c..ebc72af 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o 
spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
 # IBM PowerNV
-obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o
+obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index df55a89..aa712fd 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -569,6 +569,9 @@ static void pnv_chip_init(Object *obj)
 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
 
 chip->xscom_base = pcc->xscom_base;
+
+object_initialize(>lpc, sizeof(chip->lpc), TYPE_PNV_LPC);
+object_property_add_child(obj, "lpc", OBJECT(>lpc), NULL);
 }
 
 static void pnv_chip_realize(DeviceState *dev, Error **errp)
@@ -632,6 +635,11 @@ static void pnv_chip_realize(DeviceState *dev, Error 
**errp)
 i++;
 }
 g_free(typename);
+
+/* Create LPC controller */
+object_property_set_bool(OBJECT(>lpc), true, "realized",
+ _fatal);
+pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, >lpc.xscom_regs);
 }
 
 static Property pnv_chip_properties[] = {
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
new file mode 100644
index 000..00dbd8b
--- /dev/null
+++ b/hw/ppc/pnv_lpc.c
@@ -0,0 +1,471 @@
+/*
+ * QEMU PowerPC PowerNV LPC controller
+ *
+ * Copyright (c) 2016, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/sysemu.h"
+#include "target-ppc/cpu.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+
+#include "hw/ppc/pnv_lpc.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/fdt.h"
+
+#include 
+
+enum {
+ECCB_CTL= 0,
+ECCB_RESET  = 1,
+ECCB_STAT   = 2,
+ECCB_DATA   = 3,
+};
+
+/* OPB Master LS registers */
+#define 

[Qemu-devel] [PULL 35/73] pseries: Remove rtas_addr and fdt_addr fields from machinestate

2016-10-27 Thread David Gibson
These values are used only within ppc_spapr_reset(), so just change them
to local variables.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 14 +++---
 include/hw/ppc/spapr.h |  1 -
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 874f53d..9c38fe0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1135,6 +1135,7 @@ static void ppc_spapr_reset(void)
 sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
 PowerPCCPU *first_ppc_cpu;
 uint32_t rtas_limit;
+hwaddr rtas_addr, fdt_addr;
 void *fdt;
 int rc;
 
@@ -1160,14 +1161,13 @@ static void ppc_spapr_reset(void)
  * processed with 32-bit real mode code if necessary
  */
 rtas_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR);
-spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE;
-spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE;
+rtas_addr = rtas_limit - RTAS_MAX_SIZE;
+fdt_addr = rtas_addr - FDT_MAX_SIZE;
 
-fdt = spapr_build_fdt(spapr, spapr->rtas_addr, spapr->rtas_size);
+fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
 
 /* Copy RTAS over */
-cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
-  spapr->rtas_size);
+cpu_physical_memory_write(rtas_addr, spapr->rtas_blob, spapr->rtas_size);
 
 rc = fdt_pack(fdt);
 
@@ -1182,12 +1182,12 @@ static void ppc_spapr_reset(void)
 
 /* Load the fdt */
 qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
-cpu_physical_memory_write(spapr->fdt_addr, fdt, fdt_totalsize(fdt));
+cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
 g_free(fdt);
 
 /* Set up the entry state */
 first_ppc_cpu = POWERPC_CPU(first_cpu);
-first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
+first_ppc_cpu->env.gpr[3] = fdt_addr;
 first_ppc_cpu->env.gpr[5] = 0;
 first_cpu->halted = 0;
 first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index aeaba3e..1174741 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -63,7 +63,6 @@ struct sPAPRMachineState {
 uint32_t htab_shift;
 hwaddr rma_size;
 int vrma_adjust;
-hwaddr fdt_addr, rtas_addr;
 ssize_t rtas_size;
 void *rtas_blob;
 void *fdt_skel;
-- 
2.7.4




[Qemu-devel] [PULL 41/73] pseries: Consolidate construction of /rtas device tree node

2016-10-27 Thread David Gibson
For historical reasons construction of the /rtas node in the device
tree (amongst others) is split into several places.  In particular
it's split between spapr_create_fdt_skel(), spapr_build_fdt() and
spapr_rtas_device_tree_setup().

In fact, as well as adding the actual RTAS tokens to the device tree,
spapr_rtas_device_tree_setup() just adds the ibm,lrdr-capacity
property, which despite going in the /rtas node, doesn't have a lot to
do with RTAS.

This patch consolidates the code constructing /rtas together into a new
spapr_dt_rtas() function.  spapr_rtas_device_tree_setup() is renamed to
spapr_dt_rtas_tokens() and now only adds the token properties.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 130 +++--
 hw/ppc/spapr_rtas.c|  33 ++---
 include/hw/ppc/spapr.h |   3 +-
 3 files changed, 76 insertions(+), 90 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1d8dd7f..1b61de2 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -274,25 +274,8 @@ static void add_str(GString *s, const gchar *s1)
 static void *spapr_create_fdt_skel(sPAPRMachineState *spapr)
 {
 void *fdt;
-GString *hypertas = g_string_sized_new(256);
-GString *qemu_hypertas = g_string_sized_new(256);
-uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
 char *buf;
 
-add_str(hypertas, "hcall-pft");
-add_str(hypertas, "hcall-term");
-add_str(hypertas, "hcall-dabr");
-add_str(hypertas, "hcall-interrupt");
-add_str(hypertas, "hcall-tce");
-add_str(hypertas, "hcall-vio");
-add_str(hypertas, "hcall-splpar");
-add_str(hypertas, "hcall-bulk");
-add_str(hypertas, "hcall-set-mode");
-add_str(hypertas, "hcall-sprg0");
-add_str(hypertas, "hcall-copy");
-add_str(hypertas, "hcall-debug");
-add_str(qemu_hypertas, "hcall-memop1");
-
 fdt = g_malloc0(FDT_MAX_SIZE);
 _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
 
@@ -333,41 +316,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState 
*spapr)
 _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
 _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
 
-/* RTAS */
-_FDT((fdt_begin_node(fdt, "rtas")));
-
-if (!kvm_enabled() || kvmppc_spapr_use_multitce()) {
-add_str(hypertas, "hcall-multi-tce");
-}
-_FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas->str,
-   hypertas->len)));
-g_string_free(hypertas, TRUE);
-_FDT((fdt_property(fdt, "qemu,hypertas-functions", qemu_hypertas->str,
-   qemu_hypertas->len)));
-g_string_free(qemu_hypertas, TRUE);
-
-_FDT((fdt_property(fdt, "ibm,associativity-reference-points",
-refpoints, sizeof(refpoints;
-
-_FDT((fdt_property_cell(fdt, "rtas-error-log-max", RTAS_ERROR_LOG_MAX)));
-_FDT((fdt_property_cell(fdt, "rtas-event-scan-rate",
-RTAS_EVENT_SCAN_RATE)));
-
-if (msi_nonbroken) {
-_FDT((fdt_property(fdt, "ibm,change-msix-capable", NULL, 0)));
-}
-
-/*
- * According to PAPR, rtas ibm,os-term does not guarantee a return
- * back to the guest cpu.
- *
- * While an additional ibm,extended-os-term property indicates that
- * rtas call return will always occur. Set this property.
- */
-_FDT((fdt_property(fdt, "ibm,extended-os-term", NULL, 0)));
-
-_FDT((fdt_end_node(fdt)));
-
 /* vdevice */
 _FDT((fdt_begin_node(fdt, "vdevice")));
 
@@ -840,6 +788,75 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 return 0;
 }
 
+static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
+{
+int rtas;
+GString *hypertas = g_string_sized_new(256);
+GString *qemu_hypertas = g_string_sized_new(256);
+uint32_t refpoints[] = { cpu_to_be32(0x4), cpu_to_be32(0x4) };
+uint64_t max_hotplug_addr = spapr->hotplug_memory.base +
+memory_region_size(>hotplug_memory.mr);
+uint32_t lrdr_capacity[] = {
+cpu_to_be32(max_hotplug_addr >> 32),
+cpu_to_be32(max_hotplug_addr & 0x),
+0, cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE),
+cpu_to_be32(max_cpus / smp_threads),
+};
+
+_FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
+
+/* hypertas */
+add_str(hypertas, "hcall-pft");
+add_str(hypertas, "hcall-term");
+add_str(hypertas, "hcall-dabr");
+add_str(hypertas, "hcall-interrupt");
+add_str(hypertas, "hcall-tce");
+add_str(hypertas, "hcall-vio");
+add_str(hypertas, "hcall-splpar");
+add_str(hypertas, "hcall-bulk");
+add_str(hypertas, "hcall-set-mode");
+add_str(hypertas, "hcall-sprg0");
+add_str(hypertas, "hcall-copy");
+add_str(hypertas, "hcall-debug");
+add_str(qemu_hypertas, "hcall-memop1");
+
+if (!kvm_enabled() || kvmppc_spapr_use_multitce()) {
+add_str(hypertas, 

[Qemu-devel] [PULL 36/73] pseries: Make spapr_create_fdt_skel() get information from machine state

2016-10-27 Thread David Gibson
Currently spapr_create_fdt_skel() takes a bunch of individual parameters
for various things it will put in the device tree.  Some of these can
already be taken directly from sPAPRMachineState.  This patch alters it so
that all of them can be taken from there, which will allow this code to
be moved away from its current caller in future.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 81 ++
 include/hw/ppc/spapr.h |  4 +++
 2 files changed, 40 insertions(+), 45 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9c38fe0..3b23920 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -271,16 +271,12 @@ static void add_str(GString *s, const gchar *s1)
 g_string_append_len(s, s1, strlen(s1) + 1);
 }
 
-static void *spapr_create_fdt_skel(hwaddr initrd_base,
-   hwaddr initrd_size,
-   hwaddr kernel_size,
-   bool little_endian,
-   const char *kernel_cmdline,
-   uint32_t epow_irq)
+static void *spapr_create_fdt_skel(sPAPRMachineState *spapr)
 {
+MachineState *machine = MACHINE(spapr);
 void *fdt;
-uint32_t start_prop = cpu_to_be32(initrd_base);
-uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
+uint32_t start_prop = cpu_to_be32(spapr->initrd_base);
+uint32_t end_prop = cpu_to_be32(spapr->initrd_base + spapr->initrd_size);
 GString *hypertas = g_string_sized_new(256);
 GString *qemu_hypertas = g_string_sized_new(256);
 uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
@@ -305,11 +301,13 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
 fdt = g_malloc0(FDT_MAX_SIZE);
 _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
 
-if (kernel_size) {
-_FDT((fdt_add_reservemap_entry(fdt, KERNEL_LOAD_ADDR, kernel_size)));
+if (spapr->kernel_size) {
+_FDT((fdt_add_reservemap_entry(fdt, KERNEL_LOAD_ADDR,
+   spapr->kernel_size)));
 }
-if (initrd_size) {
-_FDT((fdt_add_reservemap_entry(fdt, initrd_base, initrd_size)));
+if (spapr->initrd_size) {
+_FDT((fdt_add_reservemap_entry(fdt, spapr->initrd_base,
+   spapr->initrd_size)));
 }
 _FDT((fdt_finish_reservemap(fdt)));
 
@@ -354,17 +352,17 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
 /* Set Form1_affinity */
 _FDT((fdt_property(fdt, "ibm,architecture-vec-5", vec5, sizeof(vec5;
 
-_FDT((fdt_property_string(fdt, "bootargs", kernel_cmdline)));
+_FDT((fdt_property_string(fdt, "bootargs", machine->kernel_cmdline)));
 _FDT((fdt_property(fdt, "linux,initrd-start",
_prop, sizeof(start_prop;
 _FDT((fdt_property(fdt, "linux,initrd-end",
_prop, sizeof(end_prop;
-if (kernel_size) {
+if (spapr->kernel_size) {
 uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR),
-  cpu_to_be64(kernel_size) };
+  cpu_to_be64(spapr->kernel_size) };
 
 _FDT((fdt_property(fdt, "qemu,boot-kernel", , sizeof(kprop;
-if (little_endian) {
+if (spapr->kernel_le) {
 _FDT((fdt_property(fdt, "qemu,boot-kernel-le", NULL, 0)));
 }
 }
@@ -441,7 +439,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
 _FDT((fdt_end_node(fdt)));
 
 /* event-sources */
-spapr_events_fdt_skel(fdt, epow_irq);
+spapr_events_fdt_skel(fdt, spapr->check_exception_irq);
 
 /* /hypervisor node */
 if (kvm_enabled()) {
@@ -1686,7 +1684,6 @@ static void ppc_spapr_init(MachineState *machine)
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
 const char *kernel_filename = machine->kernel_filename;
-const char *kernel_cmdline = machine->kernel_cmdline;
 const char *initrd_filename = machine->initrd_filename;
 PCIHostState *phb;
 int i;
@@ -1696,10 +1693,7 @@ static void ppc_spapr_init(MachineState *machine)
 void *rma = NULL;
 hwaddr rma_alloc_size;
 hwaddr node0_size = spapr_node0_size();
-uint32_t initrd_base = 0;
-long kernel_size = 0, initrd_size = 0;
 long load_limit, fw_size;
-bool kernel_le = false;
 char *filename;
 int smt = kvmppc_smt_threads();
 int spapr_cores = smp_cpus / smp_threads;
@@ -1972,19 +1966,19 @@ static void ppc_spapr_init(MachineState *machine)
 if (kernel_filename) {
 uint64_t lowaddr = 0;
 
-kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
-   NULL, , NULL, 1, PPC_ELF_MACHINE,
- 

[Qemu-devel] [PULL 44/73] pseries: Consolidate construction of /vdevice device tree node

2016-10-27 Thread David Gibson
Construction of the /vdevice node (and its children) is divided between
spapr_create_fdt_skel() (at init time), which creates the base node, and
spapr_populate_vdevice() (at reset time) which creates the nodes for each
individual virtual device.

This consolidates both into a single function called from
spapr_build_fdt().

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 19 ++-
 hw/ppc/spapr_vio.c | 23 ---
 include/hw/ppc/spapr_vio.h |  2 +-
 3 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 261be68..34846da 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -316,18 +316,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState 
*spapr)
 _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
 _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
 
-/* vdevice */
-_FDT((fdt_begin_node(fdt, "vdevice")));
-
-_FDT((fdt_property_string(fdt, "device_type", "vdevice")));
-_FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice")));
-_FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
-_FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
-_FDT((fdt_property_cell(fdt, "#interrupt-cells", 0x2)));
-_FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
-
-_FDT((fdt_end_node(fdt)));
-
 _FDT((fdt_end_node(fdt))); /* close root node */
 _FDT((fdt_finish(fdt)));
 
@@ -943,11 +931,8 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 exit(1);
 }
 
-ret = spapr_populate_vdevice(spapr->vio_bus, fdt);
-if (ret < 0) {
-error_report("couldn't setup vio devices in fdt");
-exit(1);
-}
+/* /vdevice */
+spapr_dt_vdevice(spapr->vio_bus, fdt);
 
 if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL)) {
 ret = spapr_rng_populate_dt(fdt);
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 2b67df0..cc1e09c 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -36,6 +36,7 @@
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "hw/ppc/xics.h"
+#include "hw/ppc/fdt.h"
 #include "trace.h"
 
 #include 
@@ -624,11 +625,21 @@ static int compare_reg(const void *p1, const void *p2)
 return 1;
 }
 
-int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
+void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
 {
 DeviceState *qdev, **qdevs;
 BusChild *kid;
 int i, num, ret = 0;
+int node;
+
+_FDT(node = fdt_add_subnode(fdt, 0, "vdevice"));
+
+_FDT(fdt_setprop_string(fdt, node, "device_type", "vdevice"));
+_FDT(fdt_setprop_string(fdt, node, "compatible", "IBM,vdevice"));
+_FDT(fdt_setprop_cell(fdt, node, "#address-cells", 1));
+_FDT(fdt_setprop_cell(fdt, node, "#size-cells", 0));
+_FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
+_FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
 
 /* Count qdevs on the bus list */
 num = 0;
@@ -650,19 +661,17 @@ int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
  * to know that will mean they are in forward order in the tree. */
 for (i = num - 1; i >= 0; i--) {
 VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]);
+VIOsPAPRDeviceClass *vdc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
 
 ret = vio_make_devnode(dev, fdt);
-
 if (ret < 0) {
-goto out;
+error_report("Couldn't create device node /vdevice/%s@%"PRIx32,
+ vdc->dt_name, dev->reg);
+exit(1);
 }
 }
 
-ret = 0;
-out:
 g_free(qdevs);
-
-return ret;
 }
 
 gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus)
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index a0e7542..14f5022 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -80,7 +80,7 @@ struct VIOsPAPRBus {
 
 extern VIOsPAPRBus *spapr_vio_bus_init(void);
 extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
-extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
+void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt);
 extern gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus);
 
 static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
-- 
2.7.4




[Qemu-devel] [PULL 33/73] target-ppc: add vmul10[u, eu, cu, ecu]q instructions

2016-10-27 Thread David Gibson
From: Vasant Hegde 

vmul10uq  : Vector Multiply-by-10 Unsigned Quadword VX-form
vmul10euq : Vector Multiply-by-10 Extended Unsigned Quadword VX-form
vmul10cuq : Vector Multiply-by-10 & write Carry Unsigned Quadword VX-form
vmul10ecuq: Vector Multiply-by-10 Extended & write Carry Unsigned Quadword 
VX-form

Signed-off-by: Vasant Hegde 
[ Add GEN_VXFORM_DUAL_EXT with invalid bit mask ]
Signed-off-by: Nikunj A Dadhania 
Signed-off-by: David Gibson 
---
 target-ppc/translate/vmx-impl.inc.c | 72 +
 target-ppc/translate/vmx-ops.inc.c  |  8 ++---
 2 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index 563f101..fc612d9 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -182,6 +182,52 @@ static void gen_mtvscr(DisasContext *ctx)
 tcg_temp_free_ptr(p);
 }
 
+#define GEN_VX_VMUL10(name, add_cin, ret_carry) \
+static void glue(gen_, name)(DisasContext *ctx) \
+{   \
+TCGv_i64 t0 = tcg_temp_new_i64();   \
+TCGv_i64 t1 = tcg_temp_new_i64();   \
+TCGv_i64 t2 = tcg_temp_new_i64();   \
+TCGv_i64 ten, z;\
+\
+if (unlikely(!ctx->altivec_enabled)) {  \
+gen_exception(ctx, POWERPC_EXCP_VPU);   \
+return; \
+}   \
+\
+ten = tcg_const_i64(10);\
+z = tcg_const_i64(0);   \
+\
+if (add_cin) {  \
+tcg_gen_mulu2_i64(t0, t1, cpu_avrl[rA(ctx->opcode)], ten);  \
+tcg_gen_andi_i64(t2, cpu_avrl[rB(ctx->opcode)], 0xF);   \
+tcg_gen_add2_i64(cpu_avrl[rD(ctx->opcode)], t2, t0, t1, t2, z); \
+} else {\
+tcg_gen_mulu2_i64(cpu_avrl[rD(ctx->opcode)], t2,\
+  cpu_avrl[rA(ctx->opcode)], ten);  \
+}   \
+\
+if (ret_carry) {\
+tcg_gen_mulu2_i64(t0, t1, cpu_avrh[rA(ctx->opcode)], ten);  \
+tcg_gen_add2_i64(t0, cpu_avrl[rD(ctx->opcode)], t0, t1, t2, z); \
+tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0); \
+} else {\
+tcg_gen_mul_i64(t0, cpu_avrh[rA(ctx->opcode)], ten);\
+tcg_gen_add_i64(cpu_avrh[rD(ctx->opcode)], t0, t2); \
+}   \
+\
+tcg_temp_free_i64(t0);  \
+tcg_temp_free_i64(t1);  \
+tcg_temp_free_i64(t2);  \
+tcg_temp_free_i64(ten); \
+tcg_temp_free_i64(z);   \
+}   \
+
+GEN_VX_VMUL10(vmul10uq, 0, 0);
+GEN_VX_VMUL10(vmul10euq, 1, 0);
+GEN_VX_VMUL10(vmul10cuq, 0, 1);
+GEN_VX_VMUL10(vmul10ecuq, 1, 1);
+
 /* Logical operations */
 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)\
 static void glue(gen_, name)(DisasContext *ctx)
 \
@@ -276,8 +322,30 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx) 
\
 }  \
 }
 
+/* Adds support to provide invalid mask */
+#define GEN_VXFORM_DUAL_EXT(name0, flg0, flg2_0, inval0,\
+name1, flg1, flg2_1, inval1)\
+static void glue(gen_, name0##_##name1)(DisasContext *ctx)  \
+{   \
+if ((Rc(ctx->opcode) == 0) &&   \
+((ctx->insns_flags & 

[Qemu-devel] [PULL 28/73] ppc/pnv: add a PnvCore object

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

This is largy inspired by sPAPRCPUCore with some simplification, no
hotplug for instance. A set of PnvCore objects is added to the PnvChip
and the device tree is populated looping on these cores.

Real HW cpu ids are now generated depending on the chip cpu model, the
chip id and a core mask. The id is propagated to the CPU object, using
properties, to set the SPR_PIR (Processor Identification Register)

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/Makefile.objs  |   2 +-
 hw/ppc/pnv.c  | 189 +-
 hw/ppc/pnv_core.c | 182 
 include/hw/ppc/pnv.h  |   2 +
 include/hw/ppc/pnv_core.h |  48 
 5 files changed, 421 insertions(+), 2 deletions(-)
 create mode 100644 hw/ppc/pnv_core.c
 create mode 100644 include/hw/ppc/pnv_core.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 8105db7..f8c7d1d 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o 
spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
 # IBM PowerNV
-obj-$(CONFIG_POWERNV) += pnv.o
+obj-$(CONFIG_POWERNV) += pnv.o pnv_core.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 825d28c..3413107 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -27,6 +27,7 @@
 #include "hw/ppc/fdt.h"
 #include "hw/ppc/ppc.h"
 #include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_core.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
 #include "qemu/cutils.h"
@@ -75,12 +76,160 @@ static void powernv_populate_memory_node(void *fdt, int 
chip_id, hwaddr start,
 _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id)));
 }
 
+static int get_cpus_node(void *fdt)
+{
+int cpus_offset = fdt_path_offset(fdt, "/cpus");
+
+if (cpus_offset < 0) {
+cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"),
+  "cpus");
+if (cpus_offset) {
+_FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0x1)));
+_FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0)));
+}
+}
+_FDT(cpus_offset);
+return cpus_offset;
+}
+
+/*
+ * The PowerNV cores (and threads) need to use real HW ids and not an
+ * incremental index like it has been done on other platforms. This HW
+ * id is stored in the CPU PIR, it is used to create cpu nodes in the
+ * device tree, used in XSCOM to address cores and in interrupt
+ * servers.
+ */
+static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt)
+{
+CPUState *cs = CPU(DEVICE(pc->threads));
+DeviceClass *dc = DEVICE_GET_CLASS(cs);
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+int smt_threads = ppc_get_compat_smt_threads(cpu);
+CPUPPCState *env = >env;
+PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+uint32_t servers_prop[smt_threads];
+int i;
+uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
+   0x, 0x};
+uint32_t tbfreq = PNV_TIMEBASE_FREQ;
+uint32_t cpufreq = 10;
+uint32_t page_sizes_prop[64];
+size_t page_sizes_prop_size;
+const uint8_t pa_features[] = { 24, 0,
+0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xf0,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
+int offset;
+char *nodename;
+int cpus_offset = get_cpus_node(fdt);
+
+nodename = g_strdup_printf("%s@%x", dc->fw_name, pc->pir);
+offset = fdt_add_subnode(fdt, cpus_offset, nodename);
+_FDT(offset);
+g_free(nodename);
+
+_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id)));
+
+_FDT((fdt_setprop_cell(fdt, offset, "reg", pc->pir)));
+_FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pc->pir)));
+_FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
+
+_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
+_FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
+env->dcache_line_size)));
+_FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
+env->dcache_line_size)));
+_FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
+env->icache_line_size)));
+_FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
+env->icache_line_size)));
+
+if (pcc->l1_dcache_size) {
+_FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
+   pcc->l1_dcache_size)));
+ 

[Qemu-devel] [PULL 21/73] ppc: Fix single step with gdb stub

2016-10-27 Thread David Gibson
From: Benjamin Herrenschmidt 

Signed-off-by: Benjamin Herrenschmidt 
Signed-off-by: David Gibson 
---
 target-ppc/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 94989b2..43505a9 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -322,7 +322,7 @@ static void gen_debug_exception(DisasContext *ctx)
  */
 if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
 (ctx->exception != POWERPC_EXCP_SYNC)) {
-gen_update_nip(ctx, ctx->nip - 4);
+gen_update_nip(ctx, ctx->nip);
 }
 t0 = tcg_const_i32(EXCP_DEBUG);
 gen_helper_raise_exception(cpu_env, t0);
-- 
2.7.4




[Qemu-devel] [PULL 43/73] pseries: Move /hypervisor node construction to fdt_build_fdt()

2016-10-27 Thread David Gibson
Currently the /hypervisor device tree node is constructed in
spapr_create_fdt_skel().  As part of consolidating device tree construction
to reset time, move it to a function called from spapr_build_fdt().

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 49 -
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 048fb3d..261be68 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -328,27 +328,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState 
*spapr)
 
 _FDT((fdt_end_node(fdt)));
 
-/* /hypervisor node */
-if (kvm_enabled()) {
-uint8_t hypercall[16];
-
-/* indicate KVM hypercall interface */
-_FDT((fdt_begin_node(fdt, "hypervisor")));
-_FDT((fdt_property_string(fdt, "compatible", "linux,kvm")));
-if (kvmppc_has_cap_fixup_hcalls()) {
-/*
- * Older KVM versions with older guest kernels were broken with the
- * magic page, don't allow the guest to map it.
- */
-if (!kvmppc_get_hypercall(first_cpu->env_ptr, hypercall,
-  sizeof(hypercall))) {
-_FDT((fdt_property(fdt, "hcall-instructions", hypercall,
-   sizeof(hypercall;
-}
-}
-_FDT((fdt_end_node(fdt)));
-}
-
 _FDT((fdt_end_node(fdt))); /* close root node */
 _FDT((fdt_finish(fdt)));
 
@@ -916,6 +895,29 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void 
*fdt)
 g_free(bootlist);
 }
 
+static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt)
+{
+/* The /hypervisor node isn't in PAPR - this is a hack to allow PR
+ * KVM to work under pHyp with some guest co-operation */
+int hypervisor;
+uint8_t hypercall[16];
+
+_FDT(hypervisor = fdt_add_subnode(fdt, 0, "hypervisor"));
+/* indicate KVM hypercall interface */
+_FDT(fdt_setprop_string(fdt, hypervisor, "compatible", "linux,kvm"));
+if (kvmppc_has_cap_fixup_hcalls()) {
+/*
+ * Older KVM versions with older guest kernels were broken
+ * with the magic page, don't allow the guest to map it.
+ */
+if (!kvmppc_get_hypercall(first_cpu->env_ptr, hypercall,
+  sizeof(hypercall))) {
+_FDT(fdt_setprop(fdt, hypervisor, "hcall-instructions",
+ hypercall, sizeof(hypercall)));
+}
+}
+}
+
 static void *spapr_build_fdt(sPAPRMachineState *spapr,
  hwaddr rtas_addr,
  hwaddr rtas_size)
@@ -989,6 +991,11 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
 /* /chosen */
 spapr_dt_chosen(spapr, fdt);
 
+/* /hypervisor */
+if (kvm_enabled()) {
+spapr_dt_hypervisor(spapr, fdt);
+}
+
 /* Build memory reserve map */
 if (spapr->kernel_size) {
 _FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size)));
-- 
2.7.4




[Qemu-devel] [PULL 25/73] ppc/pnv: add a PnvChip object

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

This is is an abstraction of a POWER8 chip which is a set of cores
plus other 'units', like the pervasive unit, the interrupt controller,
the memory controller, the on-chip microcontroller, etc. The whole can
be seen as a socket. It depends on a cpu model and its characteristics:
max cores and specific inits are defined in a PnvChipClass.

We start with an near empty PnvChip with only a few cpu constants
which we will grow in the subsequent patches with the controllers
required to run the system.

The Chip CFAM (Common FRU Access Module) ID gives the model of the
chip and its version number. It is generally the first thing firmwares
fetch, available at XSCOM PCB address 0xf000f, to start initialization.

Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 213 +--
 include/hw/ppc/pnv.h |  63 +++
 2 files changed, 271 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8d98509..aeafd7e 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -30,6 +30,7 @@
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
 #include "qemu/cutils.h"
+#include "qapi/visitor.h"
 
 #include 
 
@@ -74,6 +75,14 @@ static void powernv_populate_memory_node(void *fdt, int 
chip_id, hwaddr start,
 _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id)));
 }
 
+static void powernv_populate_chip(PnvChip *chip, void *fdt)
+{
+if (chip->ram_size) {
+powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start,
+ chip->ram_size);
+}
+}
+
 static void *powernv_create_fdt(MachineState *machine)
 {
 const char plat_compat[] = "qemu,powernv\0ibm,powernv";
@@ -81,6 +90,7 @@ static void *powernv_create_fdt(MachineState *machine)
 void *fdt;
 char *buf;
 int off;
+int i;
 
 fdt = g_malloc0(FDT_MAX_SIZE);
 _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
@@ -116,11 +126,10 @@ static void *powernv_create_fdt(MachineState *machine)
_prop, sizeof(end_prop;
 }
 
-/* TODO: put all the memory in one node on chip 0 until we find a
- * way to specify different ranges for each chip
- */
-powernv_populate_memory_node(fdt, 0, 0, machine->ram_size);
-
+/* Populate device tree for each chip */
+for (i = 0; i < pnv->num_chips; i++) {
+powernv_populate_chip(pnv->chips[i], fdt);
+}
 return fdt;
 }
 
@@ -145,6 +154,8 @@ static void ppc_powernv_init(MachineState *machine)
 MemoryRegion *ram;
 char *fw_filename;
 long fw_size;
+int i;
+char *chip_typename;
 
 /* allocate RAM */
 if (machine->ram_size < (1 * G_BYTE)) {
@@ -194,6 +205,190 @@ static void ppc_powernv_init(MachineState *machine)
 exit(1);
 }
 }
+
+/* We need some cpu model to instantiate the PnvChip class */
+if (machine->cpu_model == NULL) {
+machine->cpu_model = "POWER8";
+}
+
+/* Create the processor chips */
+chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model);
+if (!object_class_by_name(chip_typename)) {
+error_report("qemu: invalid CPU model '%s' for %s machine",
+ machine->cpu_model, MACHINE_GET_CLASS(machine)->name);
+exit(1);
+}
+
+pnv->chips = g_new0(PnvChip *, pnv->num_chips);
+for (i = 0; i < pnv->num_chips; i++) {
+char chip_name[32];
+Object *chip = object_new(chip_typename);
+
+pnv->chips[i] = PNV_CHIP(chip);
+
+/* TODO: put all the memory in one node on chip 0 until we find a
+ * way to specify different ranges for each chip
+ */
+if (i == 0) {
+object_property_set_int(chip, machine->ram_size, "ram-size",
+_fatal);
+}
+
+snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));
+object_property_add_child(OBJECT(pnv), chip_name, chip, _fatal);
+object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
+_fatal);
+object_property_set_bool(chip, true, "realized", _fatal);
+}
+g_free(chip_typename);
+}
+
+static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PnvChipClass *k = PNV_CHIP_CLASS(klass);
+
+k->cpu_model = "POWER8E";
+k->chip_type = PNV_CHIP_POWER8E;
+k->chip_cfam_id = 0x221ef0498000ull;  /* P8 Murano DD2.1 */
+dc->desc = "PowerNV Chip POWER8E";
+}
+
+static const TypeInfo pnv_chip_power8e_info = {
+.name  = TYPE_PNV_CHIP_POWER8E,
+.parent= TYPE_PNV_CHIP,
+.instance_size = sizeof(PnvChip),
+.class_init= pnv_chip_power8e_class_init,
+};
+
+static void pnv_chip_power8_class_init(ObjectClass 

[Qemu-devel] [PULL 17/73] ppc/xics: add a XICSState backlink in ICPState

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

The link will be used to change the API of the icp_* routines which
are still using an XICSState as an argument.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics.c| 1 +
 include/hw/ppc/xics.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index c051eeb..9f2c81a 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -198,6 +198,7 @@ void xics_set_nr_servers(XICSState *xics, uint32_t 
nr_servers,
 object_initialize(icp, sizeof(*icp), typename);
 snprintf(name, sizeof(name), "icp[%d]", i);
 object_property_add_child(OBJECT(xics), name, OBJECT(icp), errp);
+icp->xics = xics;
 }
 }
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 573b192..1468d6a 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -117,6 +117,8 @@ struct ICPState {
 uint8_t mfrr;
 qemu_irq output;
 bool cap_irq_xics_enabled;
+
+XICSState *xics;
 };
 
 #define TYPE_ICS_BASE "ics-base"
-- 
2.7.4




[Qemu-devel] [PULL 07/73] tests: use qtest_pc_boot()/qtest_shutdown() in virtio tests

2016-10-27 Thread David Gibson
From: Laurent Vivier 

This patch replaces calls to qtest_start() and qtest_end() by
calls to qtest_pc_boot() and qtest_shutdown().

This allows to initialize memory allocator and PCI interface
functions. This will ease to enable virtio tests on other
architectures by only adding a specific qtest_XXX_boot() (like
qtest_spapr_boot()).

Signed-off-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 tests/virtio-9p-test.c   |  50 +++-
 tests/virtio-blk-test.c  | 148 ---
 tests/virtio-net-test.c  |  39 +
 tests/virtio-scsi-test.c |  67 ++---
 4 files changed, 128 insertions(+), 176 deletions(-)

diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 2341622..851ec99 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -10,62 +10,57 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 #include "qemu-common.h"
-#include "libqos/pci-pc.h"
+#include "libqos/libqos-pc.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
 #include "standard-headers/linux/virtio_ids.h"
 #include "standard-headers/linux/virtio_pci.h"
 
 static const char mount_tag[] = "qtest";
 static char *test_share;
 
-static void qvirtio_9p_start(void)
+
+static QOSState *qvirtio_9p_start(void)
 {
-char *args;
+const char *cmd = "-fsdev local,id=fsdev0,security_model=none,path=%s "
+  "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s";
 
 test_share = g_strdup("/tmp/qtest.XX");
 g_assert_nonnull(mkdtemp(test_share));
 
-args = g_strdup_printf("-fsdev local,id=fsdev0,security_model=none,path=%s 
"
-   "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s",
-   test_share, mount_tag);
-
-qtest_start(args);
-g_free(args);
+return qtest_pc_boot(cmd, test_share, mount_tag);
 }
 
-static void qvirtio_9p_stop(void)
+static void qvirtio_9p_stop(QOSState *qs)
 {
-qtest_end();
+qtest_shutdown(qs);
 rmdir(test_share);
 g_free(test_share);
 }
 
 static void pci_nop(void)
 {
-qvirtio_9p_start();
-qvirtio_9p_stop();
+QOSState *qs;
+
+qs = qvirtio_9p_start();
+qvirtio_9p_stop(qs);
 }
 
 typedef struct {
 QVirtioDevice *dev;
-QGuestAllocator *alloc;
-QPCIBus *bus;
+QOSState *qs;
 QVirtQueue *vq;
 } QVirtIO9P;
 
-static QVirtIO9P *qvirtio_9p_pci_init(void)
+static QVirtIO9P *qvirtio_9p_pci_init(QOSState *qs)
 {
 QVirtIO9P *v9p;
 QVirtioPCIDevice *dev;
 
 v9p = g_new0(QVirtIO9P, 1);
-v9p->alloc = pc_alloc_init();
-v9p->bus = qpci_init_pc(NULL);
 
-dev = qvirtio_pci_device_find(v9p->bus, VIRTIO_ID_9P);
+v9p->qs = qs;
+dev = qvirtio_pci_device_find(v9p->qs->pcibus, VIRTIO_ID_9P);
 g_assert_nonnull(dev);
 g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P);
 v9p->dev = (QVirtioDevice *) dev;
@@ -75,17 +70,15 @@ static QVirtIO9P *qvirtio_9p_pci_init(void)
 qvirtio_set_acknowledge(v9p->dev);
 qvirtio_set_driver(v9p->dev);
 
-v9p->vq = qvirtqueue_setup(v9p->dev, v9p->alloc, 0);
+v9p->vq = qvirtqueue_setup(v9p->dev, v9p->qs->alloc, 0);
 return v9p;
 }
 
 static void qvirtio_9p_pci_free(QVirtIO9P *v9p)
 {
-qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->alloc);
-pc_alloc_uninit(v9p->alloc);
+qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->qs->alloc);
 qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));
 g_free(v9p->dev);
-qpci_free_pc(v9p->bus);
 g_free(v9p);
 }
 
@@ -96,9 +89,10 @@ static void pci_basic_config(void)
 size_t tag_len;
 char *tag;
 int i;
+QOSState *qs;
 
-qvirtio_9p_start();
-v9p = qvirtio_9p_pci_init();
+qs = qvirtio_9p_start();
+v9p = qvirtio_9p_pci_init(qs);
 
 addr = ((QVirtioPCIDevice *) v9p->dev)->addr + 
VIRTIO_PCI_CONFIG_OFF(false);
 tag_len = qvirtio_config_readw(v9p->dev,
@@ -114,7 +108,7 @@ static void pci_basic_config(void)
 g_free(tag);
 
 qvirtio_9p_pci_free(v9p);
-qvirtio_9p_stop();
+qvirtio_9p_stop(qs);
 }
 
 int main(int argc, char **argv)
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 79e21c5..2382eb5 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -10,12 +10,10 @@
 
 #include "qemu/osdep.h"
 #include "libqtest.h"
+#include "libqos/libqos-pc.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
 #include "libqos/virtio-mmio.h"
-#include "libqos/pci-pc.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
 #include "libqos/malloc-generic.h"
 #include "qemu/bswap.h"
 #include "standard-headers/linux/virtio_ids.h"
@@ -58,24 +56,21 @@ static char *drive_create(void)
 return tmp_path;
 }
 
-static QPCIBus *pci_test_start(void)
+static QOSState *pci_test_start(void)
 {
-  

[Qemu-devel] [PULL 18/73] ppc/xics: change the icp_ routines API to use an 'ICPState *' argument

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

The routines :

void icp_set_cppr(ICPState *icp, uint8_t cppr);
void icp_set_mfrr(ICPState *icp, uint8_t mfrr);
void icp_eoi(ICPState *icp, uint32_t xirr);

now use one 'ICPState *icp' argument instead of a 'XICSState *' and a
server arguments. The backlink on XICSState* is used whenever needed.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics.c| 25 ++---
 hw/intc/xics_spapr.c  | 18 +++---
 include/hw/ppc/xics.h |  6 +++---
 3 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 9f2c81a..095c16a 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -326,22 +326,20 @@ static void icp_check_ipi(ICPState *ss)
 qemu_irq_raise(ss->output);
 }
 
-static void icp_resend(XICSState *xics, int server)
+static void icp_resend(ICPState *ss)
 {
-ICPState *ss = xics->ss + server;
 ICSState *ics;
 
 if (ss->mfrr < CPPR(ss)) {
 icp_check_ipi(ss);
 }
-QLIST_FOREACH(ics, >ics, list) {
+QLIST_FOREACH(ics, >xics->ics, list) {
 ics_resend(ics);
 }
 }
 
-void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
+void icp_set_cppr(ICPState *ss, uint8_t cppr)
 {
-ICPState *ss = xics->ss + server;
 uint8_t old_cppr;
 uint32_t old_xisr;
 
@@ -361,15 +359,13 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t 
cppr)
 }
 } else {
 if (!XISR(ss)) {
-icp_resend(xics, server);
+icp_resend(ss);
 }
 }
 }
 
-void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr)
+void icp_set_mfrr(ICPState *ss, uint8_t mfrr)
 {
-ICPState *ss = xics->ss + server;
-
 ss->mfrr = mfrr;
 if (mfrr < CPPR(ss)) {
 icp_check_ipi(ss);
@@ -398,23 +394,22 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
 return ss->xirr;
 }
 
-void icp_eoi(XICSState *xics, int server, uint32_t xirr)
+void icp_eoi(ICPState *ss, uint32_t xirr)
 {
-ICPState *ss = xics->ss + server;
 ICSState *ics;
 uint32_t irq;
 
 /* Send EOI -> ICS */
 ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
-trace_xics_icp_eoi(server, xirr, ss->xirr);
+trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr);
 irq = xirr & XISR_MASK;
-QLIST_FOREACH(ics, >ics, list) {
+QLIST_FOREACH(ics, >xics->ics, list) {
 if (ics_valid_irq(ics, irq)) {
 ics_eoi(ics, irq);
 }
 }
 if (!XISR(ss)) {
-icp_resend(xics, server);
+icp_resend(ss);
 }
 }
 
@@ -673,7 +668,7 @@ static int ics_simple_post_load(ICSState *ics, int 
version_id)
 int i;
 
 for (i = 0; i < ics->xics->nr_servers; i++) {
-icp_resend(ics->xics, i);
+icp_resend(>xics->ss[i]);
 }
 
 return 0;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index a09e1b0..b4e5501 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -43,9 +43,10 @@ static target_ulong h_cppr(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
 {
 CPUState *cs = CPU(cpu);
+ICPState *icp = >xics->ss[cs->cpu_index];
 target_ulong cppr = args[0];
 
-icp_set_cppr(spapr->xics, cs->cpu_index, cppr);
+icp_set_cppr(icp, cppr);
 return H_SUCCESS;
 }
 
@@ -59,7 +60,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState 
*spapr,
 return H_PARAMETER;
 }
 
-icp_set_mfrr(spapr->xics, server, mfrr);
+icp_set_mfrr(spapr->xics->ss + server, mfrr);
 return H_SUCCESS;
 }
 
@@ -67,7 +68,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState 
*spapr,
target_ulong opcode, target_ulong *args)
 {
 CPUState *cs = CPU(cpu);
-uint32_t xirr = icp_accept(spapr->xics->ss + cs->cpu_index);
+ICPState *icp = >xics->ss[cs->cpu_index];
+uint32_t xirr = icp_accept(icp);
 
 args[0] = xirr;
 return H_SUCCESS;
@@ -77,8 +79,8 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
  target_ulong opcode, target_ulong *args)
 {
 CPUState *cs = CPU(cpu);
-ICPState *ss = >xics->ss[cs->cpu_index];
-uint32_t xirr = icp_accept(ss);
+ICPState *icp = >xics->ss[cs->cpu_index];
+uint32_t xirr = icp_accept(icp);
 
 args[0] = xirr;
 args[1] = cpu_get_host_ticks();
@@ -89,9 +91,10 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState 
*spapr,
   target_ulong opcode, target_ulong *args)
 {
 CPUState *cs = CPU(cpu);
+ICPState *icp = >xics->ss[cs->cpu_index];
 target_ulong xirr = args[0];
 
-icp_eoi(spapr->xics, cs->cpu_index, xirr);
+icp_eoi(icp, xirr);
 return H_SUCCESS;
 }
 
@@ -99,8 +102,9 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, 
sPAPRMachineState *spapr,
 target_ulong opcode, 

[Qemu-devel] [PULL 23/73] configure, ppc64: Copy skiboot.lid to build directory when configuring

2016-10-27 Thread David Gibson
From: Alexey Kardashevskiy 

When configured to compile out of tree, the configure script
copies BIOS blobs to the build directory. However since the PPC64 powernv
machine ROM has .lid extension, it is ignored and "make check" fails
when trying the powernv machine.

This adds *.lid to the list of copied blobs.

Signed-off-by: Alexey Kardashevskiy 
Signed-off-by: David Gibson 
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 8e10059..7b8e77f 100755
--- a/configure
+++ b/configure
@@ -6131,6 +6131,7 @@ FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
 FILES="$FILES pc-bios/qemu-icon.bmp"
 for bios_file in \
 $source_path/pc-bios/*.bin \
+$source_path/pc-bios/*.lid \
 $source_path/pc-bios/*.aml \
 $source_path/pc-bios/*.rom \
 $source_path/pc-bios/*.dtb \
-- 
2.7.4




[Qemu-devel] [PULL 40/73] pseries: Consolidate construction of /chosen device tree node

2016-10-27 Thread David Gibson
For historical reasons, building the /chosen node in the guest device tree
is split across several places and includes both parts which write the DT
sequentially and others which use random access functions.

This patch consolidates construction of the node into one place, using
random access functions throughout.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c | 131 ++---
 hw/ppc/spapr_vio.c |  17 ++
 include/hw/ppc/spapr_vio.h |   2 +-
 3 files changed, 70 insertions(+), 80 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 102f008..1d8dd7f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -273,14 +273,10 @@ static void add_str(GString *s, const gchar *s1)
 
 static void *spapr_create_fdt_skel(sPAPRMachineState *spapr)
 {
-MachineState *machine = MACHINE(spapr);
 void *fdt;
-uint32_t start_prop = cpu_to_be32(spapr->initrd_base);
-uint32_t end_prop = cpu_to_be32(spapr->initrd_base + spapr->initrd_size);
 GString *hypertas = g_string_sized_new(256);
 GString *qemu_hypertas = g_string_sized_new(256);
 uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
-unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
 char *buf;
 
 add_str(hypertas, "hcall-pft");
@@ -337,35 +333,6 @@ static void *spapr_create_fdt_skel(sPAPRMachineState 
*spapr)
 _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
 _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
 
-/* /chosen */
-_FDT((fdt_begin_node(fdt, "chosen")));
-
-/* Set Form1_affinity */
-_FDT((fdt_property(fdt, "ibm,architecture-vec-5", vec5, sizeof(vec5;
-
-_FDT((fdt_property_string(fdt, "bootargs", machine->kernel_cmdline)));
-_FDT((fdt_property(fdt, "linux,initrd-start",
-   _prop, sizeof(start_prop;
-_FDT((fdt_property(fdt, "linux,initrd-end",
-   _prop, sizeof(end_prop;
-if (spapr->kernel_size) {
-uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR),
-  cpu_to_be64(spapr->kernel_size) };
-
-_FDT((fdt_property(fdt, "qemu,boot-kernel", , sizeof(kprop;
-if (spapr->kernel_le) {
-_FDT((fdt_property(fdt, "qemu,boot-kernel-le", NULL, 0)));
-}
-}
-if (boot_menu) {
-_FDT((fdt_property_cell(fdt, "qemu,boot-menu", boot_menu)));
-}
-_FDT((fdt_property_cell(fdt, "qemu,graphic-width", graphic_width)));
-_FDT((fdt_property_cell(fdt, "qemu,graphic-height", graphic_height)));
-_FDT((fdt_property_cell(fdt, "qemu,graphic-depth", graphic_depth)));
-
-_FDT((fdt_end_node(fdt)));
-
 /* RTAS */
 _FDT((fdt_begin_node(fdt, "rtas")));
 
@@ -873,6 +840,68 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 return 0;
 }
 
+static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
+{
+MachineState *machine = MACHINE(spapr);
+int chosen;
+const char *boot_device = machine->boot_order;
+char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
+size_t cb = 0;
+char *bootlist = get_boot_devices_list(, true);
+unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
+
+_FDT(chosen = fdt_add_subnode(fdt, 0, "chosen"));
+
+/* Set Form1_affinity */
+_FDT(fdt_setprop(fdt, chosen, "ibm,architecture-vec-5",
+ vec5, sizeof(vec5)));
+
+_FDT(fdt_setprop_string(fdt, chosen, "bootargs", machine->kernel_cmdline));
+_FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
+  spapr->initrd_base));
+_FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-end",
+  spapr->initrd_base + spapr->initrd_size));
+
+if (spapr->kernel_size) {
+uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR),
+  cpu_to_be64(spapr->kernel_size) };
+
+_FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel",
+ , sizeof(kprop)));
+if (spapr->kernel_le) {
+_FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel-le", NULL, 0));
+}
+}
+if (boot_menu) {
+_FDT((fdt_setprop_cell(fdt, chosen, "qemu,boot-menu", boot_menu)));
+}
+_FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-width", graphic_width));
+_FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-height", graphic_height));
+_FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-depth", graphic_depth));
+
+if (cb && bootlist) {
+int i;
+
+for (i = 0; i < cb; i++) {
+if (bootlist[i] == '\n') {
+bootlist[i] = ' ';
+}
+}
+_FDT(fdt_setprop_string(fdt, chosen, "qemu,boot-list", bootlist));
+}
+
+if (boot_device && strlen(boot_device)) {
+_FDT(fdt_setprop_string(fdt, chosen, "qemu,boot-device", 

[Qemu-devel] [PULL 38/73] pseries: Consolidate RTAS loading

2016-10-27 Thread David Gibson
At each system reset, the pseries machine needs to load RTAS (the runtime
portion of the guest firmware) into the VM.  This means copying
the actual RTAS code into guest memory, and also updating the device
tree so that the guest OS and boot firmware can locate it.

For historical reasons the copy and update to the device tree were in
different parts of the code.  This cleanup brings them both together in
an spapr_load_rtas() function.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Thomas Huth 
Reviewed-by: Michael Roth 
---
 hw/ppc/spapr.c |  3 +--
 hw/ppc/spapr_rtas.c| 72 --
 include/hw/ppc/spapr.h |  1 +
 3 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8e58d86..17733df 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1165,8 +1165,7 @@ static void ppc_spapr_reset(void)
 
 fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
 
-/* Copy RTAS over */
-cpu_physical_memory_write(rtas_addr, spapr->rtas_blob, spapr->rtas_size);
+spapr_load_rtas(spapr, fdt, rtas_addr);
 
 rc = fdt_pack(fdt);
 
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 0db84c8..54b4ad3 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -721,37 +721,6 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr 
rtas_addr,
 uint64_t max_hotplug_addr = spapr->hotplug_memory.base +
 memory_region_size(>hotplug_memory.mr);
 
-ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
-if (ret < 0) {
-error_report("Couldn't add RTAS reserve entry: %s",
-fdt_strerror(ret));
-return ret;
-}
-
-ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-base",
-rtas_addr);
-if (ret < 0) {
-error_report("Couldn't add linux,rtas-base property: %s",
-fdt_strerror(ret));
-return ret;
-}
-
-ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
-rtas_addr);
-if (ret < 0) {
-error_report("Couldn't add linux,rtas-entry property: %s",
-fdt_strerror(ret));
-return ret;
-}
-
-ret = qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size",
-rtas_size);
-if (ret < 0) {
-error_report("Couldn't add rtas-size property: %s",
-fdt_strerror(ret));
-return ret;
-}
-
 for (i = 0; i < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; i++) {
 struct rtas_call *call = _table[i];
 
@@ -784,6 +753,47 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr 
rtas_addr,
 return 0;
 }
 
+void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr)
+{
+int rtas_node;
+int ret;
+
+/* Copy RTAS blob into guest RAM */
+cpu_physical_memory_write(addr, spapr->rtas_blob, spapr->rtas_size);
+
+ret = fdt_add_mem_rsv(fdt, addr, spapr->rtas_size);
+if (ret < 0) {
+error_report("Couldn't add RTAS reserve entry: %s",
+ fdt_strerror(ret));
+exit(1);
+}
+
+/* Update the device tree with the blob's location */
+rtas_node = fdt_path_offset(fdt, "/rtas");
+assert(rtas_node >= 0);
+
+ret = fdt_setprop_cell(fdt, rtas_node, "linux,rtas-base", addr);
+if (ret < 0) {
+error_report("Couldn't add linux,rtas-base property: %s",
+ fdt_strerror(ret));
+exit(1);
+}
+
+ret = fdt_setprop_cell(fdt, rtas_node, "linux,rtas-entry", addr);
+if (ret < 0) {
+error_report("Couldn't add linux,rtas-entry property: %s",
+ fdt_strerror(ret));
+exit(1);
+}
+
+ret = fdt_setprop_cell(fdt, rtas_node, "rtas-size", spapr->rtas_size);
+if (ret < 0) {
+error_report("Couldn't add rtas-size property: %s",
+ fdt_strerror(ret));
+exit(1);
+}
+}
+
 static void core_rtas_register_types(void)
 {
 spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index a0b4bf8..847ae88 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -532,6 +532,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, 
sPAPRMachineState *sm,
  uint32_t nret, target_ulong rets);
 int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
  hwaddr rtas_size);
+void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr);
 
 #define SPAPR_TCE_PAGE_SHIFT   12
 #define SPAPR_TCE_PAGE_SIZE(1ULL << SPAPR_TCE_PAGE_SHIFT)
-- 
2.7.4




[Qemu-devel] [PULL 27/73] ppc/pnv: add a PIR handler to PnvChip

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

The Processor Identification Register (PIR) is a register that holds a
processor identifier which is used for bus transactions (XSCOM) and
for processor differentiation in multiprocessor systems. It also used
in the interrupt vector entries (IVE) to identify the thread serving
the interrupts.

P9 and P8 have some differences in the CPU PIR encoding.

Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 30 ++
 include/hw/ppc/pnv.h |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 1705699..825d28c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -244,6 +244,32 @@ static void ppc_powernv_init(MachineState *machine)
 g_free(chip_typename);
 }
 
+/*
+ *0:21  Reserved - Read as zeros
+ *   22:24  Chip ID
+ *   25:28  Core number
+ *   29:31  Thread ID
+ */
+static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
+{
+return (chip->chip_id << 7) | (core_id << 3);
+}
+
+/*
+ *0:48  Reserved - Read as zeroes
+ *   49:52  Node ID
+ *   53:55  Chip ID
+ *   56 Reserved - Read as zero
+ *   57:61  Core number
+ *   62:63  Thread ID
+ *
+ * We only care about the lower bits. uint32_t is fine for the moment.
+ */
+static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
+{
+return (chip->chip_id << 8) | (core_id << 2);
+}
+
 /* Allowed core identifiers on a POWER8 Processor Chip :
  *
  * 
@@ -279,6 +305,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, 
void *data)
 k->chip_type = PNV_CHIP_POWER8E;
 k->chip_cfam_id = 0x221ef0498000ull;  /* P8 Murano DD2.1 */
 k->cores_mask = POWER8E_CORE_MASK;
+k->core_pir = pnv_chip_core_pir_p8;
 dc->desc = "PowerNV Chip POWER8E";
 }
 
@@ -298,6 +325,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, 
void *data)
 k->chip_type = PNV_CHIP_POWER8;
 k->chip_cfam_id = 0x220ea0498000ull; /* P8 Venice DD2.0 */
 k->cores_mask = POWER8_CORE_MASK;
+k->core_pir = pnv_chip_core_pir_p8;
 dc->desc = "PowerNV Chip POWER8";
 }
 
@@ -317,6 +345,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 k->chip_type = PNV_CHIP_POWER8NVL;
 k->chip_cfam_id = 0x120d30498000ull;  /* P8 Naples DD1.0 */
 k->cores_mask = POWER8_CORE_MASK;
+k->core_pir = pnv_chip_core_pir_p8;
 dc->desc = "PowerNV Chip POWER8NVL";
 }
 
@@ -336,6 +365,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, 
void *data)
 k->chip_type = PNV_CHIP_POWER9;
 k->chip_cfam_id = 0x100d10498000ull; /* P9 Nimbus DD1.0 */
 k->cores_mask = POWER9_CORE_MASK;
+k->core_pir = pnv_chip_core_pir_p9;
 dc->desc = "PowerNV Chip POWER9";
 }
 
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index e084a8c..b7987f8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -58,6 +58,8 @@ typedef struct PnvChipClass {
 PnvChipType  chip_type;
 uint64_t chip_cfam_id;
 uint64_t cores_mask;
+
+uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
 } PnvChipClass;
 
 #define TYPE_PNV_CHIP_POWER8E TYPE_PNV_CHIP "-POWER8E"
-- 
2.7.4




[Qemu-devel] [PULL 13/73] nvram: Rename openbios_firmware_abi.h into sun_nvram.h

2016-10-27 Thread David Gibson
From: Thomas Huth 

The header now only contains inline functions related to the
Sun NVRAM, so the a name like sun_nvram.h seems to be more
appropriate now.

Signed-off-by: Thomas Huth 
Tested-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/sparc/sun4m.c  | 2 +-
 hw/sparc64/sun4u.c| 2 +-
 include/hw/nvram/{openbios_firmware_abi.h => sun_nvram.h} | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)
 rename include/hw/nvram/{openbios_firmware_abi.h => sun_nvram.h} (90%)

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 1b8d172..6224288 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -35,10 +35,10 @@
 #include "sysemu/sysemu.h"
 #include "net/net.h"
 #include "hw/boards.h"
-#include "hw/nvram/openbios_firmware_abi.h"
 #include "hw/scsi/esp.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/isa.h"
+#include "hw/nvram/sun_nvram.h"
 #include "hw/nvram/chrp_nvram.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/char/escc.h"
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 83708ab..271d8bc 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -36,7 +36,7 @@
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
-#include "hw/nvram/openbios_firmware_abi.h"
+#include "hw/nvram/sun_nvram.h"
 #include "hw/nvram/chrp_nvram.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
diff --git a/include/hw/nvram/openbios_firmware_abi.h 
b/include/hw/nvram/sun_nvram.h
similarity index 90%
rename from include/hw/nvram/openbios_firmware_abi.h
rename to include/hw/nvram/sun_nvram.h
index 27ce9f4..68eaa60 100644
--- a/include/hw/nvram/openbios_firmware_abi.h
+++ b/include/hw/nvram/sun_nvram.h
@@ -1,5 +1,5 @@
-#ifndef OPENBIOS_FIRMWARE_ABI_H
-#define OPENBIOS_FIRMWARE_ABI_H
+#ifndef SUN_NVRAM_H
+#define SUN_NVRAM_H
 
 /* Sun IDPROM structure at the end of NVRAM */
 /* from http://www.squirrel.com/squirrel/sun-nvram-hostid.faq.html */
@@ -31,4 +31,4 @@ Sun_init_header(struct Sun_nvram *header, const uint8_t 
*macaddr, int machine_id
 
 header->checksum = tmp;
 }
-#endif /* OPENBIOS_FIRMWARE_ABI_H */
+#endif /* SUN_NVRAM_H */
-- 
2.7.4




[Qemu-devel] [PULL 20/73] pseries: Remove unused callbacks from sPAPR VIO bus state

2016-10-27 Thread David Gibson
The original QOMification of the spapr VIO devices in 3954d33 "spapr:
convert to QEMU Object Model (v2)" moved some callbacks from the
VIOsPAPRBus structure to the VIOsPAPRDeviceClass.  Except, that it
forgot to actually remove them from the VIOsPAPRBus structure (which
still exists, though it doesn't fulfill quite the same function as it
did pre-QOM).

This patch removes those now unused callback fields.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
Reviewed-by: Thomas Huth 
---
 include/hw/ppc/spapr_vio.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 40d0e5f..0b025fd 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -76,8 +76,6 @@ struct VIOsPAPRDevice {
 struct VIOsPAPRBus {
 BusState bus;
 uint32_t next_reg;
-int (*init)(VIOsPAPRDevice *dev);
-int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
 };
 
 extern VIOsPAPRBus *spapr_vio_bus_init(void);
-- 
2.7.4




[Qemu-devel] [PULL 06/73] tests: rename target_big_endian() as qvirtio_is_big_endian()

2016-10-27 Thread David Gibson
From: Laurent Vivier 

Move the definition to libqos/virtio.h as it must be used
only with virtio functions.

Add a QVirtioDevice parameter as it will be needed to
know if the virtio device is using virtio 1.0 specification
and thus is always little-endian (to do)

Signed-off-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
Reviewed-by: Thomas Huth 
Signed-off-by: David Gibson 
---
 tests/libqos/virtio-pci.c |  2 +-
 tests/libqos/virtio.h |  6 ++
 tests/libqtest.h  | 10 --
 tests/virtio-blk-test.c   | 36 ++--
 4 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index bbfed58..7aa29b1 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -86,7 +86,7 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, 
uint64_t addr)
 int i;
 uint64_t u64 = 0;
 
-if (target_big_endian()) {
+if (qvirtio_is_big_endian(d)) {
 for (i = 0; i < 8; ++i) {
 u64 |= (uint64_t)qpci_io_readb(dev->pdev,
 (void *)(uintptr_t)addr + i) << (7 - i) * 8;
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index ac4669a..3397a08 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -89,6 +89,12 @@ struct QVirtioBus {
 void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
 };
 
+static inline bool qvirtio_is_big_endian(QVirtioDevice *d)
+{
+/* FIXME: virtio 1.0 is always little-endian */
+return qtest_big_endian(global_qtest);
+}
+
 static inline uint32_t qvring_size(uint32_t num, uint32_t align)
 {
 return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (3 + num)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 4be1f77..0224f06 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -881,16 +881,6 @@ static inline int64_t clock_set(int64_t val)
 return qtest_clock_set(global_qtest, val);
 }
 
-/**
- * target_big_endian:
- *
- * Returns: True if the architecture under test has a big endian configuration.
- */
-static inline bool target_big_endian(void)
-{
-return qtest_big_endian(global_qtest);
-}
-
 QDict *qmp_fd_receive(int fd);
 void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
 void qmp_fd_send(int fd, const char *fmt, ...);
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 9a6f2cf..79e21c5 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -117,23 +117,23 @@ static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus 
*bus, int slot)
 return dev;
 }
 
-static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
+static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
 {
 #ifdef HOST_WORDS_BIGENDIAN
-bool host_endian = true;
+const bool host_is_big_endian = true;
 #else
-bool host_endian = false;
+const bool host_is_big_endian = false;
 #endif
 
-if (target_big_endian() != host_endian) {
+if (qvirtio_is_big_endian(d) != host_is_big_endian) {
 req->type = bswap32(req->type);
 req->ioprio = bswap32(req->ioprio);
 req->sector = bswap64(req->sector);
 }
 }
 
-static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
-uint64_t data_size)
+static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
+   QVirtioBlkReq *req, uint64_t data_size)
 {
 uint64_t addr;
 uint8_t status = 0xFF;
@@ -141,7 +141,7 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, 
QVirtioBlkReq *req,
 g_assert_cmpuint(data_size % 512, ==, 0);
 addr = guest_alloc(alloc, sizeof(*req) + data_size);
 
-virtio_blk_fix_request(req);
+virtio_blk_fix_request(d, req);
 
 memwrite(addr, req, 16);
 memwrite(addr + 16, req->data, data_size);
@@ -182,7 +182,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 req.data = g_malloc0(512);
 strcpy(req.data, "TEST");
 
-req_addr = virtio_blk_request(alloc, , 512);
+req_addr = virtio_blk_request(alloc, dev, , 512);
 
 g_free(req.data);
 
@@ -204,7 +204,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 req.sector = 0;
 req.data = g_malloc0(512);
 
-req_addr = virtio_blk_request(alloc, , 512);
+req_addr = virtio_blk_request(alloc, dev, , 512);
 
 g_free(req.data);
 
@@ -234,7 +234,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 req.data = g_malloc0(512);
 strcpy(req.data, "TEST");
 
-req_addr = virtio_blk_request(alloc, , 512);
+req_addr = virtio_blk_request(alloc, dev, , 512);
 
 g_free(req.data);
 
@@ -254,7 +254,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 req.sector = 1;
 req.data = 

[Qemu-devel] [PULL 15/73] target-ppc: implement xxbr[qdwh] instruction

2016-10-27 Thread David Gibson
From: Nikunj A Dadhania 

Add required helpers (GEN_XX2FORM_EO) for supporting this instruction.

xxbrh: VSX Vector Byte-Reverse Halfword
xxbrw: VSX Vector Byte-Reverse Word
xxbrd: VSX Vector Byte-Reverse Doubleword
xxbrq: VSX Vector Byte-Reverse Quadword

Signed-off-by: Nikunj A Dadhania 
Reviewed-by: Richard Henderson 
Signed-off-by: David Gibson 
---
 target-ppc/translate.c  | 32 +++
 target-ppc/translate/vsx-impl.inc.c | 77 +
 target-ppc/translate/vsx-ops.inc.c  |  8 
 3 files changed, 117 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index dab8f19..94989b2 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -376,6 +376,9 @@ GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, 
type2)
 #define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2) \
 GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2)
 
+#define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) 
\
+GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2)
+
 typedef struct opcode_t {
 unsigned char opc1, opc2, opc3, opc4;
 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
@@ -662,6 +665,21 @@ EXTRACT_HELPER(IMM8, 11, 8);
 },\
 .oname = stringify(name), \
 }
+#define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2)\
+{ \
+.opc1 = op1,  \
+.opc2 = op2,  \
+.opc3 = op3,  \
+.opc4 = op4,  \
+.handler = {  \
+.inval1  = invl,  \
+.type = _typ, \
+.type2 = _typ2,   \
+.handler = _##name,   \
+.oname = onam,\
+},\
+.oname = onam,\
+}
 #else
 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)\
 { \
@@ -720,6 +738,20 @@ EXTRACT_HELPER(IMM8, 11, 8);
 },\
 .oname = stringify(name), \
 }
+#define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2)\
+{ \
+.opc1 = op1,  \
+.opc2 = op2,  \
+.opc3 = op3,  \
+.opc4 = op4,  \
+.handler = {  \
+.inval1  = invl,  \
+.type = _typ, \
+.type2 = _typ2,   \
+.handler = _##name,   \
+},\
+.oname = onam,\
+}
 #endif
 
 /* SPR load/store helpers */
diff --git a/target-ppc/translate/vsx-impl.inc.c 
b/target-ppc/translate/vsx-impl.inc.c
index 23ec1e1..1508bd1 100644
--- a/target-ppc/translate/vsx-impl.inc.c
+++ b/target-ppc/translate/vsx-impl.inc.c
@@ -132,6 +132,22 @@ static void gen_bswap16x8(TCGv_i64 outh, TCGv_i64 outl,
 tcg_temp_free_i64(mask);
 }
 
+static void gen_bswap32x4(TCGv_i64 outh, TCGv_i64 outl,
+  TCGv_i64 inh, TCGv_i64 inl)
+{
+TCGv_i64 hi = tcg_temp_new_i64();
+TCGv_i64 lo = tcg_temp_new_i64();
+
+tcg_gen_bswap64_i64(hi, inh);
+tcg_gen_bswap64_i64(lo, inl);
+tcg_gen_shri_i64(outh, hi, 32);
+tcg_gen_deposit_i64(outh, outh, hi, 32, 32);
+tcg_gen_shri_i64(outl, lo, 32);
+tcg_gen_deposit_i64(outl, outl, lo, 32, 32);
+
+tcg_temp_free_i64(hi);
+tcg_temp_free_i64(lo);
+}
 static void 

[Qemu-devel] [PULL 46/73] spapr_ovec: initial implementation of option vector helpers

2016-10-27 Thread David Gibson
From: Michael Roth 

PAPR guests advertise their capabilities to the platform by passing
an ibm,architecture-vec structure via an
ibm,client-architecture-support hcall as described by LoPAPR v11,
B.6.2.3. during early boot.

Using this information, the platform enables the capabilities it
supports, then encodes a subset of those enabled capabilities (the
5th option vector of the ibm,architecture-vec structure passed to
ibm,client-architecture-support) into the guest device tree via
"/chosen/ibm,architecture-vec-5".

The logical format of these these option vectors is a bit-vector,
where individual bits are addressed/documented based on the byte-wise
offset from the beginning of the bit-vector, followed by the bit-wise
index starting from the byte-wise offset. Thus the bits of each of
these bytes are stored in reverse order. Additionally, the first
byte of each option vector is encodes the length of the option vector,
so byte offsets begin at 1, and bit offset at 0.

This is not very intuitive for the purposes of mapping these bits to
a particular documented capability, so this patch introduces a set
of abstractions that encapsulate the work of parsing/encoding these
options vectors and testing for individual capabilities.

Cc: Bharata B Rao 
Signed-off-by: Michael Roth 
[dwg: Tweaked double-include protection to not trigger a checkpatch
 false positive]
Signed-off-by: David Gibson 
---
 hw/ppc/Makefile.objs|   2 +-
 hw/ppc/spapr_ovec.c | 242 
 include/hw/ppc/spapr_ovec.h |  62 
 3 files changed, 305 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/spapr_ovec.c
 create mode 100644 include/hw/ppc/spapr_ovec.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index ebc72af..8025129 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -4,7 +4,7 @@ obj-y += ppc.o ppc_booke.o fdt.o
 obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
 obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
-obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
+obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
 # IBM PowerNV
 obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c
new file mode 100644
index 000..c2a0d18
--- /dev/null
+++ b/hw/ppc/spapr_ovec.c
@@ -0,0 +1,242 @@
+/*
+ * QEMU SPAPR Architecture Option Vector Helper Functions
+ *
+ * Copyright IBM Corp. 2016
+ *
+ * Authors:
+ *  Bharata B Rao 
+ *  Michael Roth  
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/ppc/spapr_ovec.h"
+#include "qemu/bitmap.h"
+#include "exec/address-spaces.h"
+#include "qemu/error-report.h"
+#include 
+
+/* #define DEBUG_SPAPR_OVEC */
+
+#ifdef DEBUG_SPAPR_OVEC
+#define DPRINTFN(fmt, ...) \
+do { fprintf(stderr, fmt "\n", ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTFN(fmt, ...) \
+do { } while (0)
+#endif
+
+#define OV_MAXBYTES 256 /* not including length byte */
+#define OV_MAXBITS (OV_MAXBYTES * BITS_PER_BYTE)
+
+/* we *could* work with bitmaps directly, but handling the bitmap privately
+ * allows us to more safely make assumptions about the bitmap size and
+ * simplify the calling code somewhat
+ */
+struct sPAPROptionVector {
+unsigned long *bitmap;
+};
+
+sPAPROptionVector *spapr_ovec_new(void)
+{
+sPAPROptionVector *ov;
+
+ov = g_new0(sPAPROptionVector, 1);
+ov->bitmap = bitmap_new(OV_MAXBITS);
+
+return ov;
+}
+
+sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig)
+{
+sPAPROptionVector *ov;
+
+g_assert(ov_orig);
+
+ov = spapr_ovec_new();
+bitmap_copy(ov->bitmap, ov_orig->bitmap, OV_MAXBITS);
+
+return ov;
+}
+
+void spapr_ovec_intersect(sPAPROptionVector *ov,
+  sPAPROptionVector *ov1,
+  sPAPROptionVector *ov2)
+{
+g_assert(ov);
+g_assert(ov1);
+g_assert(ov2);
+
+bitmap_and(ov->bitmap, ov1->bitmap, ov2->bitmap, OV_MAXBITS);
+}
+
+/* returns true if options bits were removed, false otherwise */
+bool spapr_ovec_diff(sPAPROptionVector *ov,
+ sPAPROptionVector *ov_old,
+ sPAPROptionVector *ov_new)
+{
+unsigned long *change_mask = bitmap_new(OV_MAXBITS);
+unsigned long *removed_bits = bitmap_new(OV_MAXBITS);
+bool bits_were_removed = false;
+
+g_assert(ov);
+g_assert(ov_old);
+g_assert(ov_new);
+
+bitmap_xor(change_mask, ov_old->bitmap, ov_new->bitmap, OV_MAXBITS);
+bitmap_and(ov->bitmap, ov_new->bitmap, change_mask, 

[Qemu-devel] [PULL 08/73] tests: enable virtio tests on SPAPR

2016-10-27 Thread David Gibson
From: Laurent Vivier 

but disable MSI-X tests on SPAPR as we can't check the result
(the memory region used on PC is not readable on SPAPR).

Signed-off-by: Laurent Vivier 
Signed-off-by: David Gibson 
---
 tests/Makefile.include|  3 ++-
 tests/libqos/virtio-pci.c | 24 ++--
 tests/virtio-9p-test.c| 12 +++-
 tests/virtio-blk-test.c   | 25 -
 tests/virtio-net-test.c   | 18 --
 tests/virtio-rng-test.c   |  7 ++-
 tests/virtio-scsi-test.c  | 12 +++-
 7 files changed, 88 insertions(+), 13 deletions(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 22656ea..1a135d2 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -282,6 +282,7 @@ check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF)
 gcov-files-ppc64-y += hw/usb/hcd-uhci.c
 check-qtest-ppc64-y += tests/usb-hcd-xhci-test$(EXESUF)
 gcov-files-ppc64-y += hw/usb/hcd-xhci.c
+check-qtest-ppc64-y += $(check-qtest-virtio-y)
 
 check-qtest-sh4-y = tests/endianness-test$(EXESUF)
 
@@ -615,7 +616,7 @@ libqos-pc-obj-y += tests/libqos/ahci.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
 libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
 libqos-usb-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/usb.o
-libqos-virtio-obj-y = $(libqos-pc-obj-y) tests/libqos/virtio.o 
tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o 
tests/libqos/malloc-generic.o
+libqos-virtio-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) 
tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o 
tests/libqos/malloc-generic.o
 
 tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o
 tests/rtc-test$(EXESUF): tests/rtc-test.o
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 7aa29b1..7e60b3a 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -68,16 +68,36 @@ static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, 
uint64_t addr)
 return qpci_io_readb(dev->pdev, (void *)(uintptr_t)addr);
 }
 
+/* PCI is always read in little-endian order
+ * but virtio ( < 1.0) is in guest order
+ * so with a big-endian guest the order has been reversed,
+ * reverse it again
+ * virtio-1.0 is always little-endian, like PCI, but this
+ * case will be managed inside qvirtio_is_big_endian()
+ */
+
 static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t addr)
 {
 QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-return qpci_io_readw(dev->pdev, (void *)(uintptr_t)addr);
+uint16_t value;
+
+value = qpci_io_readw(dev->pdev, (void *)(uintptr_t)addr);
+if (qvirtio_is_big_endian(d)) {
+value = bswap16(value);
+}
+return value;
 }
 
 static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t addr)
 {
 QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-return qpci_io_readl(dev->pdev, (void *)(uintptr_t)addr);
+uint32_t value;
+
+value = qpci_io_readl(dev->pdev, (void *)(uintptr_t)addr);
+if (qvirtio_is_big_endian(d)) {
+value = bswap32(value);
+}
+return value;
 }
 
 static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 851ec99..693920a 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -11,6 +11,7 @@
 #include "libqtest.h"
 #include "qemu-common.h"
 #include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
 #include "standard-headers/linux/virtio_ids.h"
@@ -22,13 +23,22 @@ static char *test_share;
 
 static QOSState *qvirtio_9p_start(void)
 {
+const char *arch = qtest_get_arch();
 const char *cmd = "-fsdev local,id=fsdev0,security_model=none,path=%s "
   "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s";
 
 test_share = g_strdup("/tmp/qtest.XX");
 g_assert_nonnull(mkdtemp(test_share));
 
-return qtest_pc_boot(cmd, test_share, mount_tag);
+if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+return qtest_pc_boot(cmd, test_share, mount_tag);
+}
+if (strcmp(arch, "ppc64") == 0) {
+return qtest_spapr_boot(cmd, test_share, mount_tag);
+}
+
+g_printerr("virtio-9p tests are only available on x86 or ppc64\n");
+exit(EXIT_FAILURE);
 }
 
 static void qvirtio_9p_stop(QOSState *qs)
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 2382eb5..f737c40 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -11,6 +11,7 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 #include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
 #include "libqos/virtio-mmio.h"
@@ -59,6 +60,7 @@ static char *drive_create(void)
 static QOSState *pci_test_start(void)
 {
 QOSState *qs;
+const char 

[Qemu-devel] [PULL 14/73] target-ppc: implement vnegw/d instructions

2016-10-27 Thread David Gibson
From: Nikunj A Dadhania 

Vector Integer Negate Instructions:

vnegw: Vector Negate Word
vnegd: Vector Negate Doubleword

Signed-off-by: Nikunj A Dadhania 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  2 ++
 target-ppc/int_helper.c | 12 
 target-ppc/translate/vmx-impl.inc.c |  2 ++
 target-ppc/translate/vmx-ops.inc.c  |  2 ++
 4 files changed, 18 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 04c6421..5fcc546 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -272,6 +272,8 @@ DEF_HELPER_2(vextsh2w, void, avr, avr)
 DEF_HELPER_2(vextsb2d, void, avr, avr)
 DEF_HELPER_2(vextsh2d, void, avr, avr)
 DEF_HELPER_2(vextsw2d, void, avr, avr)
+DEF_HELPER_2(vnegw, void, avr, avr)
+DEF_HELPER_2(vnegd, void, avr, avr)
 DEF_HELPER_2(vupkhpx, void, avr, avr)
 DEF_HELPER_2(vupklpx, void, avr, avr)
 DEF_HELPER_2(vupkhsb, void, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 5aee0a8..dca4798 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1949,6 +1949,18 @@ VEXT_SIGNED(vextsh2d, s64, UINT16_MAX, int16_t, int64_t)
 VEXT_SIGNED(vextsw2d, s64, UINT32_MAX, int32_t, int64_t)
 #undef VEXT_SIGNED
 
+#define VNEG(name, element) \
+void helper_##name(ppc_avr_t *r, ppc_avr_t *b)  \
+{   \
+int i;  \
+VECTOR_FOR_INORDER_I(i, element) {  \
+r->element[i] = -b->element[i]; \
+}   \
+}
+VNEG(vnegw, s32)
+VNEG(vnegd, s64)
+#undef VNEG
+
 #define VSPLTI(suffix, element, splat_type) \
 void helper_vspltis##suffix(ppc_avr_t *r, uint32_t splat)   \
 {   \
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index c8998f3..563f101 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -815,6 +815,8 @@ GEN_VXFORM_NOA(vclzb, 1, 28)
 GEN_VXFORM_NOA(vclzh, 1, 29)
 GEN_VXFORM_NOA(vclzw, 1, 30)
 GEN_VXFORM_NOA(vclzd, 1, 31)
+GEN_VXFORM_NOA_2(vnegw, 1, 24, 6)
+GEN_VXFORM_NOA_2(vnegd, 1, 24, 7)
 GEN_VXFORM_NOA_2(vextsb2w, 1, 24, 16)
 GEN_VXFORM_NOA_2(vextsh2w, 1, 24, 17)
 GEN_VXFORM_NOA_2(vextsb2d, 1, 24, 24)
diff --git a/target-ppc/translate/vmx-ops.inc.c 
b/target-ppc/translate/vmx-ops.inc.c
index 68cba3e..ab64ab2 100644
--- a/target-ppc/translate/vmx-ops.inc.c
+++ b/target-ppc/translate/vmx-ops.inc.c
@@ -215,6 +215,8 @@ GEN_VXFORM_DUAL_INV(vspltish, vinserth, 6, 13, 0x, 
0x10,
 GEN_VXFORM_DUAL_INV(vspltisw, vinsertw, 6, 14, 0x, 0x10,
PPC_ALTIVEC),
 GEN_VXFORM_300_EXT(vinsertd, 6, 15, 0x10),
+GEN_VXFORM_300_EO(vnegw, 0x01, 0x18, 0x06),
+GEN_VXFORM_300_EO(vnegd, 0x01, 0x18, 0x07),
 GEN_VXFORM_300_EO(vextsb2w, 0x01, 0x18, 0x10),
 GEN_VXFORM_300_EO(vextsh2w, 0x01, 0x18, 0x11),
 GEN_VXFORM_300_EO(vextsb2d, 0x01, 0x18, 0x18),
-- 
2.7.4




[Qemu-devel] [PULL 12/73] nvram: Move the remaining CHRP NVRAM related code to chrp_nvram.[ch]

2016-10-27 Thread David Gibson
From: Thomas Huth 

Everything that is related to CHRP NVRAM should rather reside in
chrp_nvram.c / chrp_nvram.h instead of openbios_firmware_abi.h.

Signed-off-by: Thomas Huth 
Tested-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/nvram/chrp_nvram.c| 31 +++-
 hw/nvram/mac_nvram.c |  7 +++---
 include/hw/nvram/chrp_nvram.h| 30 +++
 include/hw/nvram/openbios_firmware_abi.h | 41 
 tests/postcopy-test.c|  8 +++
 5 files changed, 57 insertions(+), 60 deletions(-)

diff --git a/hw/nvram/chrp_nvram.c b/hw/nvram/chrp_nvram.c
index f6183ed..3837510 100644
--- a/hw/nvram/chrp_nvram.c
+++ b/hw/nvram/chrp_nvram.c
@@ -23,26 +23,35 @@
 #include "qemu/cutils.h"
 #include "hw/hw.h"
 #include "hw/nvram/chrp_nvram.h"
-#include "hw/nvram/openbios_firmware_abi.h"
 #include "sysemu/sysemu.h"
 
+static int chrp_nvram_set_var(uint8_t *nvram, int addr, const char *str)
+{
+int len;
+
+len = strlen(str) + 1;
+memcpy([addr], str, len);
+
+return addr + len;
+}
+
 /**
  * Create a "system partition", used for the Open Firmware
  * environment variables.
  */
 int chrp_nvram_create_system_partition(uint8_t *data, int min_len)
 {
-struct OpenBIOS_nvpart_v1 *part_header;
+ChrpNvramPartHdr *part_header;
 unsigned int i;
 int end;
 
-part_header = (struct OpenBIOS_nvpart_v1 *)data;
-part_header->signature = OPENBIOS_PART_SYSTEM;
+part_header = (ChrpNvramPartHdr *)data;
+part_header->signature = CHRP_NVPART_SYSTEM;
 pstrcpy(part_header->name, sizeof(part_header->name), "system");
 
-end = sizeof(struct OpenBIOS_nvpart_v1);
+end = sizeof(ChrpNvramPartHdr);
 for (i = 0; i < nb_prom_envs; i++) {
-end = OpenBIOS_set_var(data, end, prom_envs[i]);
+end = chrp_nvram_set_var(data, end, prom_envs[i]);
 }
 
 /* End marker */
@@ -54,7 +63,7 @@ int chrp_nvram_create_system_partition(uint8_t *data, int 
min_len)
 if (end < min_len) {
 end = min_len;
 }
-OpenBIOS_finish_partition(part_header, end);
+chrp_nvram_finish_partition(part_header, end);
 
 return end;
 }
@@ -64,13 +73,13 @@ int chrp_nvram_create_system_partition(uint8_t *data, int 
min_len)
  */
 int chrp_nvram_create_free_partition(uint8_t *data, int len)
 {
-struct OpenBIOS_nvpart_v1 *part_header;
+ChrpNvramPartHdr *part_header;
 
-part_header = (struct OpenBIOS_nvpart_v1 *)data;
-part_header->signature = OPENBIOS_PART_FREE;
+part_header = (ChrpNvramPartHdr *)data;
+part_header->signature = CHRP_NVPART_FREE;
 pstrcpy(part_header->name, sizeof(part_header->name), "free");
 
-OpenBIOS_finish_partition(part_header, len);
+chrp_nvram_finish_partition(part_header, len);
 
 return len;
 }
diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c
index c0e62a5..63f9ed1 100644
--- a/hw/nvram/mac_nvram.c
+++ b/hw/nvram/mac_nvram.c
@@ -24,7 +24,6 @@
  */
 #include "qemu/osdep.h"
 #include "hw/hw.h"
-#include "hw/nvram/openbios_firmware_abi.h"
 #include "hw/nvram/chrp_nvram.h"
 #include "hw/ppc/mac.h"
 #include "qemu/cutils.h"
@@ -163,15 +162,15 @@ static void 
pmac_format_nvram_partition_osx(MacIONVRAMState *nvr, int off,
 int len)
 {
 uint32_t start = off;
-struct OpenBIOS_nvpart_v1 *part_header;
+ChrpNvramPartHdr *part_header;
 unsigned char *data = >data[start];
 
 /* empty partition */
-part_header = (struct OpenBIOS_nvpart_v1 *)data;
+part_header = (ChrpNvramPartHdr *)data;
 part_header->signature = OSX_NVRAM_SIGNATURE;
 pstrcpy(part_header->name, sizeof(part_header->name), "");
 
-OpenBIOS_finish_partition(part_header, len);
+chrp_nvram_finish_partition(part_header, len);
 
 /* Generation */
 stl_be_p([20], 2);
diff --git a/include/hw/nvram/chrp_nvram.h b/include/hw/nvram/chrp_nvram.h
index 18d1976..b4f5b2b 100644
--- a/include/hw/nvram/chrp_nvram.h
+++ b/include/hw/nvram/chrp_nvram.h
@@ -18,6 +18,36 @@
 #ifndef CHRP_NVRAM_H
 #define CHRP_NVRAM_H
 
+/* OpenBIOS NVRAM partition */
+typedef struct {
+uint8_t signature;
+uint8_t checksum;
+uint16_t len;   /* Big endian, length divided by 16 */
+char name[12];
+} ChrpNvramPartHdr;
+
+#define CHRP_NVPART_SYSTEM 0x70
+#define CHRP_NVPART_FREE 0x7f
+
+static inline void
+chrp_nvram_finish_partition(ChrpNvramPartHdr *header, uint32_t size)
+{
+unsigned int i, sum;
+uint8_t *tmpptr;
+
+/* Length divided by 16 */
+header->len = cpu_to_be16(size >> 4);
+
+/* Checksum */
+tmpptr = (uint8_t *)header;
+sum = *tmpptr;
+for (i = 0; i < 14; i++) {
+sum += tmpptr[2 + i];
+sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
+}
+header->checksum = sum & 0xff;
+}
+
 int 

[Qemu-devel] [PULL 34/73] pseries: Split device tree construction from device tree load

2016-10-27 Thread David Gibson
spapr_finalize_fdt() both finishes building the device tree for the guest
and loads it into guest memory.  For future cleanups, it's going to be
more convenient to do these two things separately.  The loading portion is
pretty trivial, so we move it inline into the caller, ppc_spapr_reset().

We also rename spapr_finalize_fdt(), because the current name is going to
become inaccurate.

Signed-off-by: David Gibson 
Reviewed-by: Michael Roth 
Reviewed-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr.c  | 42 +++---
 hw/ppc/spapr_cpu_core.c |  2 +-
 2 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 486f57d..874f53d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -900,10 +900,9 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 return 0;
 }
 
-static void spapr_finalize_fdt(sPAPRMachineState *spapr,
-   hwaddr fdt_addr,
-   hwaddr rtas_addr,
-   hwaddr rtas_size)
+static void *spapr_build_fdt(sPAPRMachineState *spapr,
+ hwaddr rtas_addr,
+ hwaddr rtas_size)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
 MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -999,19 +998,8 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
 }
 }
 
-_FDT((fdt_pack(fdt)));
-
-if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
-error_report("FDT too big ! 0x%x bytes (max is 0x%x)",
- fdt_totalsize(fdt), FDT_MAX_SIZE);
-exit(1);
-}
-
-qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
-cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
-
 g_free(bootlist);
-g_free(fdt);
+return fdt;
 }
 
 static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
@@ -1147,6 +1135,8 @@ static void ppc_spapr_reset(void)
 sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
 PowerPCCPU *first_ppc_cpu;
 uint32_t rtas_limit;
+void *fdt;
+int rc;
 
 /* Check for unknown sysbus devices */
 foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
@@ -1173,14 +1163,28 @@ static void ppc_spapr_reset(void)
 spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE;
 spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE;
 
-/* Load the fdt */
-spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
-   spapr->rtas_size);
+fdt = spapr_build_fdt(spapr, spapr->rtas_addr, spapr->rtas_size);
 
 /* Copy RTAS over */
 cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
   spapr->rtas_size);
 
+rc = fdt_pack(fdt);
+
+/* Should only fail if we've built a corrupted tree */
+assert(rc == 0);
+
+if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
+error_report("FDT too big ! 0x%x bytes (max is 0x%x)",
+ fdt_totalsize(fdt), FDT_MAX_SIZE);
+exit(1);
+}
+
+/* Load the fdt */
+qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
+cpu_physical_memory_write(spapr->fdt_addr, fdt, fdt_totalsize(fdt));
+g_free(fdt);
+
 /* Set up the entry state */
 first_ppc_cpu = POWERPC_CPU(first_cpu);
 first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index bc922bc..e0c14f6 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -184,7 +184,7 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev,
 
 /*
  * Setup CPU DT entries only for hotplugged CPUs. For boot time or
- * coldplugged CPUs DT entries are setup in spapr_finalize_fdt().
+ * coldplugged CPUs DT entries are setup in spapr_build_fdt().
  */
 if (dev->hotplugged) {
 fdt = spapr_populate_hotplug_cpu_dt(cs, _offset, spapr);
-- 
2.7.4




Re: [Qemu-devel] [PATCH v2 3/6] target-ppc: add vrldnmi and vrlwmi instructions

2016-10-27 Thread David Gibson
On Thu, Oct 27, 2016 at 02:03:01PM +0530, Nikunj A Dadhania wrote:
> David Gibson  writes:
> >> diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
> >> index dca4798..b54cd7c 100644
> >> --- a/target-ppc/int_helper.c
> >> +++ b/target-ppc/int_helper.c
> >> @@ -1717,6 +1717,52 @@ void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t 
> >> *r, ppc_avr_t *b)
> >>  }
> >>  }
> >>  
> >> +#define MASK(size, max_val) \
> >> +static inline uint##size##_t mask_u##size(uint##size##_t start, \
> >> +uint##size##_t end) \
> >> +{   \
> >> +uint##size##_t ret, max_bit = size - 1; \
> >> +\
> >> +if (likely(start == 0)) {   \
> >> +ret = max_val << (max_bit - end);   \
> >> +} else if (likely(end == max_bit)) {\
> >> +ret = max_val >> start; \
> >> +} else {\
> >> +ret = (((uint##size##_t)(-1ULL)) >> (start)) ^  \
> >> +(((uint##size##_t)(-1ULL) >> (end)) >> 1);  \
> >> +if (unlikely(start > end)) {\
> >> +return ~ret;\
> >> +}   \
> >> +}   \
> >> +\
> >> +return ret; \
> >> +}
> >> +
> >> +MASK(32, UINT32_MAX);
> >> +MASK(64, UINT64_MAX);
> >
> > It would be nicer to merge this mask generation with the
> > implementation in target-ppc/translate.c (called MASK()).
> 
> How about something like this in target-ppc/cpu.h
> 
> #define FUNC_MASK(name, ret_type, size, max_val)  \
> static inline ret_type name (uint##size##_t start,\
>  uint##size##_t end)  \
> { \
> ret_type ret, max_bit = size - 1; \
>   \
> if (likely(start == 0)) { \
> ret = max_val << (max_bit - end); \
> } else if (likely(end == max_bit)) {  \
> ret = max_val >> start;   \
> } else {  \
> ret = (((uint##size##_t)(-1ULL)) >> (start)) ^\
> (((uint##size##_t)(-1ULL) >> (end)) >> 1);\
> if (unlikely(start > end)) {  \
> return ~ret;  \
> } \
> } \
>   \
> return ret;   \
> }
> 
> #if defined(TARGET_PPC64)
> FUNC_MASK(MASK, target_ulong, 64, UINT64_MAX);
> #else
> FUNC_MASK(MASK, target_ulong, 32, UINT32_MAX);
> #endif
> FUNC_MASK(mask_u32, uint32_t, 32, UINT32_MAX);
> FUNC_MASK(mask_u64, uint64_t, 64, UINT64_MAX);

That seems reasonable.

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


signature.asc
Description: PGP signature


[Qemu-devel] [PULL 10/73] nvram: Introduce helper functions for CHRP "system" and "free space" partitions

2016-10-27 Thread David Gibson
From: Thomas Huth 

The "system partition" and "free space" partition layouts are
defined by the CHRP and LoPAPR specification, and used by
OpenBIOS and SLOF. We can re-use this code for other machines
that use OpenBIOS and SLOF, too. So let's make this code independent
from the MAC NVRAM environment and put it into two proper helper
functions.

Signed-off-by: Thomas Huth 
Tested-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/nvram/Makefile.objs|  1 +
 hw/nvram/chrp_nvram.c | 76 +++
 hw/nvram/mac_nvram.c  | 40 +--
 include/hw/nvram/chrp_nvram.h | 24 ++
 4 files changed, 109 insertions(+), 32 deletions(-)
 create mode 100644 hw/nvram/chrp_nvram.c
 create mode 100644 include/hw/nvram/chrp_nvram.h

diff --git a/hw/nvram/Makefile.objs b/hw/nvram/Makefile.objs
index e9a6694..c018f6b 100644
--- a/hw/nvram/Makefile.objs
+++ b/hw/nvram/Makefile.objs
@@ -1,5 +1,6 @@
 common-obj-$(CONFIG_DS1225Y) += ds1225y.o
 common-obj-y += eeprom93xx.o
 common-obj-y += fw_cfg.o
+common-obj-y += chrp_nvram.o
 common-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
 obj-$(CONFIG_PSERIES) += spapr_nvram.o
diff --git a/hw/nvram/chrp_nvram.c b/hw/nvram/chrp_nvram.c
new file mode 100644
index 000..f6183ed
--- /dev/null
+++ b/hw/nvram/chrp_nvram.c
@@ -0,0 +1,76 @@
+/*
+ * Common Hardware Reference Platform NVRAM helper functions.
+ *
+ * The CHRP NVRAM layout is used by OpenBIOS and SLOF. See CHRP
+ * specification, chapter 8, or the LoPAPR specification for details
+ * about the NVRAM layout.
+ *
+ * This code 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 "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "hw/hw.h"
+#include "hw/nvram/chrp_nvram.h"
+#include "hw/nvram/openbios_firmware_abi.h"
+#include "sysemu/sysemu.h"
+
+/**
+ * Create a "system partition", used for the Open Firmware
+ * environment variables.
+ */
+int chrp_nvram_create_system_partition(uint8_t *data, int min_len)
+{
+struct OpenBIOS_nvpart_v1 *part_header;
+unsigned int i;
+int end;
+
+part_header = (struct OpenBIOS_nvpart_v1 *)data;
+part_header->signature = OPENBIOS_PART_SYSTEM;
+pstrcpy(part_header->name, sizeof(part_header->name), "system");
+
+end = sizeof(struct OpenBIOS_nvpart_v1);
+for (i = 0; i < nb_prom_envs; i++) {
+end = OpenBIOS_set_var(data, end, prom_envs[i]);
+}
+
+/* End marker */
+data[end++] = '\0';
+
+end = (end + 15) & ~15;
+/* XXX: OpenBIOS is not able to grow up a partition. Leave some space for
+   new variables. */
+if (end < min_len) {
+end = min_len;
+}
+OpenBIOS_finish_partition(part_header, end);
+
+return end;
+}
+
+/**
+ * Create a "free space" partition
+ */
+int chrp_nvram_create_free_partition(uint8_t *data, int len)
+{
+struct OpenBIOS_nvpart_v1 *part_header;
+
+part_header = (struct OpenBIOS_nvpart_v1 *)data;
+part_header->signature = OPENBIOS_PART_FREE;
+pstrcpy(part_header->name, sizeof(part_header->name), "free");
+
+OpenBIOS_finish_partition(part_header, len);
+
+return len;
+}
diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c
index 24f6121..c0e62a5 100644
--- a/hw/nvram/mac_nvram.c
+++ b/hw/nvram/mac_nvram.c
@@ -25,7 +25,7 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/nvram/openbios_firmware_abi.h"
-#include "sysemu/sysemu.h"
+#include "hw/nvram/chrp_nvram.h"
 #include "hw/ppc/mac.h"
 #include "qemu/cutils.h"
 #include 
@@ -146,38 +146,14 @@ static void macio_nvram_register_types(void)
 static void pmac_format_nvram_partition_of(MacIONVRAMState *nvr, int off,
int len)
 {
-unsigned int i;
-uint32_t start = off, end;
-struct OpenBIOS_nvpart_v1 *part_header;
+int sysp_end;
+
+/* OpenBIOS nvram variables partition */
+sysp_end = chrp_nvram_create_system_partition(>data[off],
+  DEF_SYSTEM_SIZE) + off;
 
-// OpenBIOS nvram variables
-// Variable partition
-part_header = (struct OpenBIOS_nvpart_v1 *)>data[start];
-part_header->signature = OPENBIOS_PART_SYSTEM;
-pstrcpy(part_header->name, sizeof(part_header->name), "system");
-
-end = start + sizeof(struct 

[Qemu-devel] [PULL 16/73] ppc/xics: add a xics_set_nr_servers common routine

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

xics_spapr and xics_kvm nearly define the same 'set_nr_servers'
handler. Only the type of the ICP differs. So let's make a common one
to remove some duplicated code.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics.c| 24 +---
 hw/intc/xics_kvm.c| 13 +
 hw/intc/xics_spapr.c  | 13 +
 include/hw/ppc/xics.h |  2 ++
 4 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 7fac964..c051eeb 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -183,6 +183,24 @@ static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, 
const char *name,
 info->set_nr_irqs(xics, value, errp);
 }
 
+void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
+ const char *typename, Error **errp)
+{
+int i;
+
+xics->nr_servers = nr_servers;
+
+xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
+for (i = 0; i < xics->nr_servers; i++) {
+char name[32];
+ICPState *icp = >ss[i];
+
+object_initialize(icp, sizeof(*icp), typename);
+snprintf(name, sizeof(name), "icp[%d]", i);
+object_property_add_child(OBJECT(xics), name, OBJECT(icp), errp);
+}
+}
+
 static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
  const char *name, void *opaque,
  Error **errp)
@@ -198,7 +216,7 @@ static void xics_prop_set_nr_servers(Object *obj, Visitor 
*v,
  Error **errp)
 {
 XICSState *xics = XICS_COMMON(obj);
-XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
+XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
 Error *error = NULL;
 int64_t value;
 
@@ -213,8 +231,8 @@ static void xics_prop_set_nr_servers(Object *obj, Visitor 
*v,
 return;
 }
 
-assert(info->set_nr_servers);
-info->set_nr_servers(xics, value, errp);
+assert(xsc->set_nr_servers);
+xsc->set_nr_servers(xics, value, errp);
 }
 
 static void xics_common_initfn(Object *obj)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 9c2f198..17694ea 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -373,18 +373,7 @@ static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t 
nr_irqs,
 static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
 Error **errp)
 {
-int i;
-
-xics->nr_servers = nr_servers;
-
-xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-for (i = 0; i < xics->nr_servers; i++) {
-char buffer[32];
-object_initialize(>ss[i], sizeof(xics->ss[i]), TYPE_KVM_ICP);
-snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-object_property_add_child(OBJECT(xics), buffer, OBJECT(>ss[i]),
-  errp);
-}
+xics_set_nr_servers(xics, nr_servers, TYPE_KVM_ICP, errp);
 }
 
 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index e8d0623..a09e1b0 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -249,18 +249,7 @@ static void xics_spapr_set_nr_irqs(XICSState *xics, 
uint32_t nr_irqs,
 static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
   Error **errp)
 {
-int i;
-
-xics->nr_servers = nr_servers;
-
-xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-for (i = 0; i < xics->nr_servers; i++) {
-char buffer[32];
-object_initialize(>ss[i], sizeof(xics->ss[i]), TYPE_ICP);
-snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-object_property_add_child(OBJECT(xics), buffer, OBJECT(>ss[i]),
-  errp);
-}
+xics_set_nr_servers(xics, nr_servers, TYPE_ICP, errp);
 }
 
 static void xics_spapr_realize(DeviceState *dev, Error **errp)
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 66ae55d..573b192 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -188,6 +188,8 @@ void xics_spapr_free(XICSState *icp, int irq, int num);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
 void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
+void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
+ const char *typename, Error **errp);
 
 /* Internal XICS interfaces */
 int xics_get_cpu_index_by_dt_id(int cpu_dt_id);
-- 
2.7.4




[Qemu-devel] [PULL 26/73] ppc/pnv: add a core mask to PnvChip

2016-10-27 Thread David Gibson
From: Cédric Le Goater 

This will be used to build real HW ids for the cores and enforce some
limits on the available cores per chip.

Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 73 +++-
 include/hw/ppc/pnv.h |  4 +++
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index aeafd7e..1705699 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -238,11 +238,38 @@ static void ppc_powernv_init(MachineState *machine)
 object_property_add_child(OBJECT(pnv), chip_name, chip, _fatal);
 object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
 _fatal);
+object_property_set_int(chip, smp_cores, "nr-cores", _fatal);
 object_property_set_bool(chip, true, "realized", _fatal);
 }
 g_free(chip_typename);
 }
 
+/* Allowed core identifiers on a POWER8 Processor Chip :
+ *
+ * 
+ *  EX1  - Venice only
+ *  EX2  - Venice only
+ *  EX3  - Venice only
+ *  EX4
+ *  EX5
+ *  EX6
+ *  
+ *  EX9  - Venice only
+ *  EX10 - Venice only
+ *  EX11 - Venice only
+ *  EX12
+ *  EX13
+ *  EX14
+ * 
+ */
+#define POWER8E_CORE_MASK  (0x7070ull)
+#define POWER8_CORE_MASK   (0x7e7eull)
+
+/*
+ * POWER9 has 24 cores, ids starting at 0x20
+ */
+#define POWER9_CORE_MASK   (0xffull)
+
 static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -251,6 +278,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, 
void *data)
 k->cpu_model = "POWER8E";
 k->chip_type = PNV_CHIP_POWER8E;
 k->chip_cfam_id = 0x221ef0498000ull;  /* P8 Murano DD2.1 */
+k->cores_mask = POWER8E_CORE_MASK;
 dc->desc = "PowerNV Chip POWER8E";
 }
 
@@ -269,6 +297,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, 
void *data)
 k->cpu_model = "POWER8";
 k->chip_type = PNV_CHIP_POWER8;
 k->chip_cfam_id = 0x220ea0498000ull; /* P8 Venice DD2.0 */
+k->cores_mask = POWER8_CORE_MASK;
 dc->desc = "PowerNV Chip POWER8";
 }
 
@@ -287,6 +316,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 k->cpu_model = "POWER8NVL";
 k->chip_type = PNV_CHIP_POWER8NVL;
 k->chip_cfam_id = 0x120d30498000ull;  /* P8 Naples DD1.0 */
+k->cores_mask = POWER8_CORE_MASK;
 dc->desc = "PowerNV Chip POWER8NVL";
 }
 
@@ -305,6 +335,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, 
void *data)
 k->cpu_model = "POWER9";
 k->chip_type = PNV_CHIP_POWER9;
 k->chip_cfam_id = 0x100d10498000ull; /* P9 Nimbus DD1.0 */
+k->cores_mask = POWER9_CORE_MASK;
 dc->desc = "PowerNV Chip POWER9";
 }
 
@@ -315,15 +346,55 @@ static const TypeInfo pnv_chip_power9_info = {
 .class_init= pnv_chip_power9_class_init,
 };
 
+static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
+{
+PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+int cores_max;
+
+/*
+ * No custom mask for this chip, let's use the default one from *
+ * the chip class
+ */
+if (!chip->cores_mask) {
+chip->cores_mask = pcc->cores_mask;
+}
+
+/* filter alien core ids ! some are reserved */
+if ((chip->cores_mask & pcc->cores_mask) != chip->cores_mask) {
+error_setg(errp, "warning: invalid core mask for chip Ox%"PRIx64" !",
+   chip->cores_mask);
+return;
+}
+chip->cores_mask &= pcc->cores_mask;
+
+/* now that we have a sane layout, let check the number of cores */
+cores_max = hweight_long(chip->cores_mask);
+if (chip->nr_cores > cores_max) {
+error_setg(errp, "warning: too many cores for chip ! Limit is %d",
+   cores_max);
+return;
+}
+}
+
 static void pnv_chip_realize(DeviceState *dev, Error **errp)
 {
-/* left purposely empty */
+PnvChip *chip = PNV_CHIP(dev);
+Error *error = NULL;
+
+/* Early checks on the core settings */
+pnv_chip_core_sanitize(chip, );
+if (error) {
+error_propagate(errp, error);
+return;
+}
 }
 
 static Property pnv_chip_properties[] = {
 DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
 DEFINE_PROP_UINT64("ram-start", PnvChip, ram_start, 0),
 DEFINE_PROP_UINT64("ram-size", PnvChip, ram_size, 0),
+DEFINE_PROP_UINT32("nr-cores", PnvChip, nr_cores, 1),
+DEFINE_PROP_UINT64("cores-mask", PnvChip, cores_mask, 0x0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 7189961..e084a8c 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -44,6 +44,9 @@ typedef struct PnvChip {
 uint32_t chip_id;
 uint64_t ram_start;
 uint64_t ram_size;
+
+uint32_t nr_cores;
+uint64_t cores_mask;
 

[Qemu-devel] [PULL 03/73] tests: fix memory leak in virtio-scsi-test

2016-10-27 Thread David Gibson
From: Laurent Vivier 

vs is allocated in qvirtio_scsi_pci_init() and never freed.

Signed-off-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
Reviewed-by: Thomas Huth 
Signed-off-by: David Gibson 
---
 tests/virtio-scsi-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 79088bb..94d75b1 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -64,6 +64,7 @@ static void qvirtio_scsi_pci_free(QVirtIOSCSI *vs)
 qvirtio_pci_device_disable(container_of(vs->dev, QVirtioPCIDevice, vdev));
 g_free(vs->dev);
 qpci_free_pc(vs->bus);
+g_free(vs);
 }
 
 static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,
-- 
2.7.4




[Qemu-devel] [PULL 11/73] sparc: Use the new common NVRAM functions for system and free space partition

2016-10-27 Thread David Gibson
From: Thomas Huth 

The system and free space NVRAM partitions (for OpenBIOS) are created
in exactly the same way as the Mac-style CHRP NVRAM partitions, so we
can use the new common helper functions to do this job here, too.

Signed-off-by: Thomas Huth 
Tested-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/sparc/sun4m.c   | 33 ++---
 hw/sparc64/sun4u.c | 33 ++---
 2 files changed, 12 insertions(+), 54 deletions(-)

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index b3915e4..1b8d172 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -39,6 +39,7 @@
 #include "hw/scsi/esp.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/isa.h"
+#include "hw/nvram/chrp_nvram.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/char/escc.h"
 #include "hw/empty_slot.h"
@@ -117,39 +118,17 @@ static void nvram_init(Nvram *nvram, uint8_t *macaddr,
int nvram_machine_id, const char *arch)
 {
 unsigned int i;
-uint32_t start, end;
+int sysp_end;
 uint8_t image[0x1ff0];
-struct OpenBIOS_nvpart_v1 *part_header;
 NvramClass *k = NVRAM_GET_CLASS(nvram);
 
 memset(image, '\0', sizeof(image));
 
-start = 0;
+/* OpenBIOS nvram variables partition */
+sysp_end = chrp_nvram_create_system_partition(image, 0);
 
-// OpenBIOS nvram variables
-// Variable partition
-part_header = (struct OpenBIOS_nvpart_v1 *)[start];
-part_header->signature = OPENBIOS_PART_SYSTEM;
-pstrcpy(part_header->name, sizeof(part_header->name), "system");
-
-end = start + sizeof(struct OpenBIOS_nvpart_v1);
-for (i = 0; i < nb_prom_envs; i++)
-end = OpenBIOS_set_var(image, end, prom_envs[i]);
-
-// End marker
-image[end++] = '\0';
-
-end = start + ((end - start + 15) & ~15);
-OpenBIOS_finish_partition(part_header, end - start);
-
-// free partition
-start = end;
-part_header = (struct OpenBIOS_nvpart_v1 *)[start];
-part_header->signature = OPENBIOS_PART_FREE;
-pstrcpy(part_header->name, sizeof(part_header->name), "free");
-
-end = 0x1fd0;
-OpenBIOS_finish_partition(part_header, end - start);
+/* Free space partition */
+chrp_nvram_create_free_partition([sysp_end], 0x1fd0 - sysp_end);
 
 Sun_init_header((struct Sun_nvram *)[0x1fd8], macaddr,
 nvram_machine_id);
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 7b8134e..83708ab 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -37,6 +37,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/nvram/openbios_firmware_abi.h"
+#include "hw/nvram/chrp_nvram.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
 #include "hw/ide.h"
@@ -124,39 +125,17 @@ static int sun4u_NVRAM_set_params(Nvram *nvram, uint16_t 
NVRAM_size,
   const uint8_t *macaddr)
 {
 unsigned int i;
-uint32_t start, end;
+int sysp_end;
 uint8_t image[0x1ff0];
-struct OpenBIOS_nvpart_v1 *part_header;
 NvramClass *k = NVRAM_GET_CLASS(nvram);
 
 memset(image, '\0', sizeof(image));
 
-start = 0;
+/* OpenBIOS nvram variables partition */
+sysp_end = chrp_nvram_create_system_partition(image, 0);
 
-// OpenBIOS nvram variables
-// Variable partition
-part_header = (struct OpenBIOS_nvpart_v1 *)[start];
-part_header->signature = OPENBIOS_PART_SYSTEM;
-pstrcpy(part_header->name, sizeof(part_header->name), "system");
-
-end = start + sizeof(struct OpenBIOS_nvpart_v1);
-for (i = 0; i < nb_prom_envs; i++)
-end = OpenBIOS_set_var(image, end, prom_envs[i]);
-
-// End marker
-image[end++] = '\0';
-
-end = start + ((end - start + 15) & ~15);
-OpenBIOS_finish_partition(part_header, end - start);
-
-// free partition
-start = end;
-part_header = (struct OpenBIOS_nvpart_v1 *)[start];
-part_header->signature = OPENBIOS_PART_FREE;
-pstrcpy(part_header->name, sizeof(part_header->name), "free");
-
-end = 0x1fd0;
-OpenBIOS_finish_partition(part_header, end - start);
+/* Free space partition */
+chrp_nvram_create_free_partition([sysp_end], 0x1fd0 - sysp_end);
 
 Sun_init_header((struct Sun_nvram *)[0x1fd8], macaddr, 0x80);
 
-- 
2.7.4




[Qemu-devel] [PULL 24/73] ppc/pnv: add skeleton PowerNV platform

2016-10-27 Thread David Gibson
From: Benjamin Herrenschmidt 

The goal is to emulate a PowerNV system at the level of the skiboot
firmware, which loads the OS and provides some runtime services. Power
Systems have a lower firmware (HostBoot) that does low level system
initialization, like DRAM training. This is beyond the scope of what
qemu will address in a PowerNV guest.

No devices yet, not even an interrupt controller. Just to get started,
some RAM to load the skiboot firmware, the kernel and initrd. The
device tree is fully created in the machine reset op.

Signed-off-by: Benjamin Herrenschmidt 
[clg: - updated for qemu-2.7
  - replaced fprintf by error_report
  - used a common definition of _FDT macro
  - removed VMStateDescription as migration is not yet supported
  - added IBM Copyright statements
  - reworked kernel_filename handling
  - merged PnvSystem and sPowerNVMachineState
  - removed PHANDLE_XICP
  - added ppc_create_page_sizes_prop helper
  - removed nmi support
  - removed kvm support
  - updated powernv machine to version 2.8
  - removed chips and cpus, They will be provided in another patches
  - added a machine reset routine to initialize the device tree (also)
  - french has a squelette and english a skeleton.
  - improved commit log.
  - reworked prototypes parameters
  - added a check on the ram size (thanks to Michael Ellerman)
  - fixed chip-id cell
  - changed MAX_CPUS to 2048
  - simplified memory node creation to one node only
  - removed machine version
  - rewrote the device tree creation with the fdt "rw" routines
  - s/sPowerNVMachineState/PnvMachineState/
  - etc.]
Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 default-configs/ppc64-softmmu.mak |   1 +
 hw/ppc/Makefile.objs  |   2 +
 hw/ppc/pnv.c  | 226 ++
 include/hw/ppc/pnv.h  |  38 +++
 4 files changed, 267 insertions(+)
 create mode 100644 hw/ppc/pnv.c
 create mode 100644 include/hw/ppc/pnv.h

diff --git a/default-configs/ppc64-softmmu.mak 
b/default-configs/ppc64-softmmu.mak
index db5a4d6..67a9bca 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -39,6 +39,7 @@ CONFIG_I8259=y
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_PSERIES=y
+CONFIG_POWERNV=y
 CONFIG_PREP=y
 CONFIG_MAC=y
 CONFIG_E500=y
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 99a0d4e..8105db7 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -5,6 +5,8 @@ obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
 obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
+# IBM PowerNV
+obj-$(CONFIG_POWERNV) += pnv.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
new file mode 100644
index 000..8d98509
--- /dev/null
+++ b/hw/ppc/pnv.c
@@ -0,0 +1,226 @@
+/*
+ * QEMU PowerPC PowerNV machine model
+ *
+ * Copyright (c) 2016, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/numa.h"
+#include "hw/hw.h"
+#include "target-ppc/cpu.h"
+#include "qemu/log.h"
+#include "hw/ppc/fdt.h"
+#include "hw/ppc/ppc.h"
+#include "hw/ppc/pnv.h"
+#include "hw/loader.h"
+#include "exec/address-spaces.h"
+#include "qemu/cutils.h"
+
+#include 
+
+#define FDT_MAX_SIZE0x0010
+
+#define FW_FILE_NAME"skiboot.lid"
+#define FW_LOAD_ADDR0x0
+#define FW_MAX_SIZE 0x0040
+
+#define KERNEL_LOAD_ADDR0x2000
+#define INITRD_LOAD_ADDR0x4000
+
+/*
+ * On Power Systems E880 (POWER8), the max cpus (threads) should be :
+ * 4 * 4 sockets * 12 cores * 8 threads = 1536
+ * Let's make it 2^11
+ */
+#define MAX_CPUS2048
+
+/*
+ * Memory nodes are created by hostboot, one for each range of memory
+ * that has a different "affinity". In practice, it means one range
+ * 

[Qemu-devel] [PULL 19/73] ppc: fix MSR_ME handling for system reset interrupt

2016-10-27 Thread David Gibson
From: Nicholas Piggin 

Power ISA specifies ME bit handling for system reset interrupt:

if the interrupt occurred while the thread was in power-saving
mode, set to 1; otherwise not altered

Power ISA 3.0, section 6.5 "Interrupt Definitions", Figure 64.

Signed-off-by: Nicholas Piggin 
Reviewed-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 target-ppc/excp_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 921c39d..53c4075 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -385,11 +385,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 srr1 = SPR_BOOKE_CSRR1;
 break;
 case POWERPC_EXCP_RESET: /* System reset exception   */
+/* A power-saving exception sets ME, otherwise it is unchanged */
 if (msr_pow) {
 /* indicate that we resumed from power save mode */
 msr |= 0x1;
-} else {
-new_msr &= ~((target_ulong)1 << MSR_ME);
+new_msr |= ((target_ulong)1 << MSR_ME);
 }
 
 new_msr |= (target_ulong)MSR_HVB;
-- 
2.7.4




[Qemu-devel] [PULL 02/73] ppc/xics: Add xics to the monitor "info pic" command

2016-10-27 Thread David Gibson
From: Benjamin Herrenschmidt 

Useful to debug interrupt problems.

Signed-off-by: Benjamin Herrenschmidt 
[clg: - updated for qemu-2.7
  - added a test on ->irqs as it is not necessarily allocated
(PHB3_MSI)
  - removed static variable g_xics and replace with a loop on all
children to find the xics objects.
  - rebased on InterruptStatsProvider interface ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics.c | 49 +
 1 file changed, 49 insertions(+)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index f40b000..7fac964 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -35,6 +35,8 @@
 #include "hw/ppc/xics.h"
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
+#include "monitor/monitor.h"
+#include "hw/intc/intc.h"
 
 int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
 {
@@ -90,6 +92,47 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
 }
 }
 
+static void xics_common_pic_print_info(InterruptStatsProvider *obj,
+   Monitor *mon)
+{
+XICSState *xics = XICS_COMMON(obj);
+ICSState *ics;
+uint32_t i;
+
+for (i = 0; i < xics->nr_servers; i++) {
+ICPState *icp = >ss[i];
+
+if (!icp->output) {
+continue;
+}
+monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
+   i, icp->xirr, icp->xirr_owner,
+   icp->pending_priority, icp->mfrr);
+}
+
+QLIST_FOREACH(ics, >ics, list) {
+monitor_printf(mon, "ICS %4x..%4x %p\n",
+   ics->offset, ics->offset + ics->nr_irqs - 1, ics);
+
+if (!ics->irqs) {
+continue;
+}
+
+for (i = 0; i < ics->nr_irqs; i++) {
+ICSIRQState *irq = ics->irqs + i;
+
+if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
+continue;
+}
+monitor_printf(mon, "  %4x %s %02x %02x\n",
+   ics->offset + i,
+   (irq->flags & XICS_FLAGS_IRQ_LSI) ?
+   "LSI" : "MSI",
+   irq->priority, irq->status);
+}
+}
+}
+
 /*
  * XICS Common class - parent for emulated XICS and KVM-XICS
  */
@@ -190,8 +233,10 @@ static void xics_common_initfn(Object *obj)
 static void xics_common_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
+InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
 
 dc->reset = xics_common_reset;
+ic->print_info = xics_common_pic_print_info;
 }
 
 static const TypeInfo xics_common_info = {
@@ -201,6 +246,10 @@ static const TypeInfo xics_common_info = {
 .class_size= sizeof(XICSStateClass),
 .instance_init = xics_common_initfn,
 .class_init= xics_common_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ TYPE_INTERRUPT_STATS_PROVIDER },
+{ }
+},
 };
 
 /*
-- 
2.7.4




[Qemu-devel] [PULL 09/73] spapr_pci: advertise explicit numa IDs even when there's 1 node

2016-10-27 Thread David Gibson
From: Michael Roth 

With the addition of "numa_node" properties for PHBs we began
advertising NUMA affinity in cases where nb_numa_nodes > 1.

Since the default on the guest side is to make no assumptions about
PHB NUMA affinity (defaulting to -1), there is still a valid use-case
for explicitly defining a PHB's NUMA affinity even when there's just
one node. In particular, some workloads make faulty assumptions about
/sys/bus/pci//numa_node being >= 0, warranting the use of
this property as a workaround even if there's just 1 PHB or NUMA
node.

Enable this use-case by always advertising the PHB's NUMA affinity
if "numa_node" has been explicitly set.

We could achieve this by relaxing the check to simply be
nb_numa_nodes > 0, but even safer would be to check
numa_info[nodeid].present explicitly, and to fail at start time
for cases where it does not exist.

This has an additional affect of no longer advertising PHB NUMA
affinity unconditionally if nb_numa_nodes > 1 and "numa_node"
property is unset/-1, but since the default value on the guest
side for each PHB is also -1, the behavior should be the same for
that situation. We could still retain the old behavior if desired,
but the decision seems arbitrary, so we take the simpler route.

Cc: Alexey Kardashevskiy 
Cc: Shivaprasad G. Bhat 
Signed-off-by: Michael Roth 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 2a1ccf5..7cde30e 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1392,6 +1392,12 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (sphb->numa_node != -1 &&
+(sphb->numa_node >= MAX_NODES || !numa_info[sphb->numa_node].present)) 
{
+error_setg(errp, "Invalid NUMA node ID for PCI host bridge");
+return;
+}
+
 sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);
 
 namebuf = alloca(strlen(sphb->dtbusname) + 32);
@@ -1880,7 +1886,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
 }
 
 /* Advertise NUMA via ibm,associativity */
-if (nb_numa_nodes > 1) {
+if (phb->numa_node != -1) {
 _FDT(fdt_setprop(fdt, bus_off, "ibm,associativity", associativity,
  sizeof(associativity)));
 }
-- 
2.7.4




[Qemu-devel] [PULL 04/73] tests: don't check if qtest_spapr_boot() returns NULL

2016-10-27 Thread David Gibson
From: Laurent Vivier 

qtest_spapr_boot()/qtest_pc_boot()/qtest_boot() call qtest_vboot()
and qtest_vboot() calls g_malloc(),
and g_malloc() never fails:
if memory allocation fails, the application is terminated.

Signed-off-by: Laurent Vivier 
Reviewed-by: Thomas Huth 
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 tests/libqos/libqos.c | 2 ++
 tests/rtas-test.c | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index 7abb482..6226546 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -10,6 +10,8 @@
 /**
  * Launch QEMU with the given command line,
  * and then set up interrupts and our guest malloc interface.
+ * Never returns NULL:
+ * Terminates the application in case an error is encountered.
  */
 QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)
 {
diff --git a/tests/rtas-test.c b/tests/rtas-test.c
index ba0867a..276c87e 100644
--- a/tests/rtas-test.c
+++ b/tests/rtas-test.c
@@ -14,7 +14,6 @@ static void test_rtas_get_time_of_day(void)
 time_t t1, t2;
 
 qs = qtest_spapr_boot("-machine pseries");
-g_assert(qs != NULL);
 
 t1 = time(NULL);
 ret = qrtas_get_time_of_day(qs->alloc, , );
-- 
2.7.4




Re: [Qemu-devel] [PULL 00/49] ppc-for-2.8 queue 20161026

2016-10-27 Thread David Gibson
On Thu, Oct 27, 2016 at 04:25:57PM +0200, Cédric Le Goater wrote:
> On 10/27/2016 03:34 PM, David Gibson wrote:
> > On Thu, Oct 27, 2016 at 02:06:12PM +0100, Peter Maydell wrote:
> >> On 26 October 2016 at 12:42, David Gibson  
> >> wrote:
> >>>   Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-10-25' 
> >>> into staging (2016-10-25 17:03:11 +0100)
> >>>
> >>> are available in the git repository at:
> >>>
> >>>   git://github.com/dgibson/qemu.git tags/ppc-for-2.8-20161026
> >>>
> >>> for you to fetch changes up to acb8eed32d455851773be209a1d9cd0258904b21:
> >>>
> >>>   adb: change handler only when recognized (2016-10-26 14:58:02 +1100)
> >>>
> >>> 
> >>> ppc patch queue 2016-10-26
> >>>
> >>> Highlights:
> >>>   * SLOF (pseries guest firmware) update
> >>>   * Enable a number of extra testcases on ppc / pseries
> >>>   * Added the 'powernv' machine type
> >>> - Almost enough to be minimally usable
> >>> - But still missing necessary interrupt controller updates
> >>>   * Cleanup and consolidation of NVRAM handling on several platforms
> >>> with related firmware
> >>>   * Substantial cleanup to device tree construction
> >>>   * Some more POWER9 instruction emulation
> >>>   * Cleanup to handling of pseries option vectors and CAS reboot
> >>> handling (host/guest feature negotiation mechanism)
> >>>   * Several bug fixes
> >>
> >> I'm afraid this breaks 'make check' (all configs):
> >>   GTESTER check-qtest-ppc64
> >> qemu: hardware error: qemu: could not load OPAL '(null)'
> > 
> > Ahh.. do you build out of tree?  If so that's probably the bug Alexey
> > reported.  The firmware file was added by 22/49, but 'configure'
> > wasn't updated to copy it to the build directory.
> > 
> 
> yes. I always install after the configure so I didn't catch the issue :  
> 
> So we need Alexey's  :
> 
>  "configure, ppc64: Copy skiboot.lid to build directory when configuring"

Right.  I merged that already, so I'll send a new pull request
obsoleting this one.

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


signature.asc
Description: PGP signature


[Qemu-devel] [PULL 00/73] ppc-for-2.8 queue 20161028

2016-10-27 Thread David Gibson
The following changes since commit 835f3d24b42fcbeca5c49048994a4e5d0fe905c5:

  Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-20161027-1' into 
staging (2016-10-27 17:24:29 +0100)

are available in the git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-2.8-20161028

for you to fetch changes up to 10c21b5c20bf3d20b7b0ad279db37ae89cc7937d:

  ppc: allow certain HV interrupts to be delivered to guests (2016-10-28 
11:17:35 +1100)


ppc patch queue 2016-10-28

This pull request supersedes and extends the one from 2016-10-26
(which had a build bug).

Highlights:
  * SLOF (pseries guest firmware) update
  * Enable a number of extra testcases on ppc / pseries
  * Added the 'powernv' machine type
- Almost enough to be minimally usable
- But still missing necessary interrupt controller updates
  * Cleanup and consolidation of NVRAM handling on several platforms
with related firmware
  * Substantial cleanup to device tree construction
  * Some more POWER9 instruction emulation
  * Cleanup to handling of pseries option vectors and CAS reboot
handling (host/guest feature negotiation mechanism)
  * Significant cleanups to handling of PCI devices in test cases
  * New hotplug event infrastructure
  * Memory hot unplug support for pseries
  * Several bug fixes

The NVRAM cleanup affects some Sun sparc platforms as well as ppc
ones, but have been tested by the sparc maintainer (Mark Cave-Ayland).

The test additions also include substantial general changes to the
test framework that aren't strictly ppc related.  They don't seem to
break tests on other platforms, they're for the benefit of enabling
tests on ppc and there isn't a specific maintainer for them, so
they're included in this tree.


Alexey Kardashevskiy (2):
  pseries: Update SLOF firmware image to 20161019
  configure, ppc64: Copy skiboot.lid to build directory when configuring

Benjamin Herrenschmidt (4):
  ppc/xics: Add xics to the monitor "info pic" command
  ppc: Fix single step with gdb stub
  ppc/pnv: add skeleton PowerNV platform
  ppc/pnv: add a LPC controller

Bharata B Rao (2):
  spapr: Add DRC count indexed hotplug identifier type
  spapr: Memory hot-unplug support

Cédric Le Goater (11):
  ppc/xics: add a xics_set_nr_servers common routine
  ppc/xics: add a XICSState backlink in ICPState
  ppc/xics: change the icp_ routines API to use an 'ICPState *' argument
  ppc: add skiboot firmware for the pnv platform
  ppc/pnv: add a PnvChip object
  ppc/pnv: add a core mask to PnvChip
  ppc/pnv: add a PIR handler to PnvChip
  ppc/pnv: add a PnvCore object
  ppc/pnv: add XSCOM infrastructure
  ppc/pnv: add XSCOM handlers to PnvCore
  ppc/pnv: add a ISA bus

David Gibson (26):
  pseries: Remove unused callbacks from sPAPR VIO bus state
  pseries: Split device tree construction from device tree load
  pseries: Remove rtas_addr and fdt_addr fields from machinestate
  pseries: Make spapr_create_fdt_skel() get information from machine state
  pseries: Move adding of fdt reserve map entries
  pseries: Consolidate RTAS loading
  pseries: Move construction of /interrupt-controller fdt node
  pseries: Consolidate construction of /chosen device tree node
  pseries: Consolidate construction of /rtas device tree node
  pseries: Move /event-sources construction to spapr_build_fdt()
  pseries: Move /hypervisor node construction to fdt_build_fdt()
  pseries: Consolidate construction of /vdevice device tree node
  pseries: Remove spapr_create_fdt_skel()
  libqos: Give qvirtio_config_read*() consistent semantics
  libqos: Handle PCI IO de-multiplexing in common code
  libqos: Move BAR assignment to common code
  libqos: Better handling of PCI legacy IO
  tests: Adjust tco-test to use qpci_legacy_iomap()
  libqos: Add streaming accessors for PCI MMIO
  libqos: Implement mmio accessors in terms of mem{read,write}
  tests: Clean up IO handling in ide-test
  libqos: Add 64-bit PCI IO accessors
  tests: Use qpci_mem{read,write} in ivshmem-test
  tests: Don't assume structure of PCI IO base in ahci-test
  libqos: Change PCI accessors to take opaque BAR handle
  tests: Add pseries machine to the prom-env-test, too

Hervé Poussineau (1):
  adb: change handler only when recognized

Laurent Vivier (6):
  tests: fix memory leak in virtio-scsi-test
  tests: don't check if qtest_spapr_boot() returns NULL
  tests: move QVirtioBus pointer into QVirtioDevice
  tests: rename target_big_endian() as qvirtio_is_big_endian()
  tests: use qtest_pc_boot()/qtest_shutdown() in virtio tests
  tests: enable virtio tests on SPAPR

Michael Roth (9):
  spapr_pci: advertise explicit numa IDs even when ther

[Qemu-devel] [PULL 05/73] tests: move QVirtioBus pointer into QVirtioDevice

2016-10-27 Thread David Gibson
From: Laurent Vivier 

This allows to not have to pass bus and device for every virtio functions.

Signed-off-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
Reviewed-by: Thomas Huth 
[dwg: Fix style nit]
Signed-off-by: David Gibson 
---
 tests/libqos/virtio-mmio.c |   1 +
 tests/libqos/virtio-pci.c  |   2 +
 tests/libqos/virtio.c  |  78 +++-
 tests/libqos/virtio.h  |  51 +++-
 tests/vhost-user-test.c|  33 +-
 tests/virtio-9p-test.c |  15 +++--
 tests/virtio-blk-test.c| 147 -
 tests/virtio-net-test.c|  59 +-
 tests/virtio-scsi-test.c   |  17 +++---
 9 files changed, 186 insertions(+), 217 deletions(-)

diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 0cab38f..bced680 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -199,6 +199,7 @@ QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, 
uint32_t page_size)
 dev->addr = addr;
 dev->page_size = page_size;
 dev->vdev.device_type = readl(addr + QVIRTIO_MMIO_DEVICE_ID);
+dev->vdev.bus = _mmio;
 
 writel(addr + QVIRTIO_MMIO_GUEST_PAGE_SIZE, page_size);
 
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 6e005c1..bbfed58 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -286,6 +286,8 @@ QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, 
uint16_t device_type)
 QVirtioPCIDevice *dev = NULL;
 qvirtio_pci_foreach(bus, device_type, qvirtio_pci_assign_device, );
 
+dev->vdev.bus = _pci;
+
 return dev;
 }
 
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 105bcce..ec30cb9 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -13,45 +13,40 @@
 #include "standard-headers/linux/virtio_config.h"
 #include "standard-headers/linux/virtio_ring.h"
 
-uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
-uint64_t addr)
+uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr)
 {
-return bus->config_readb(d, addr);
+return d->bus->config_readb(d, addr);
 }
 
-uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
-uint64_t addr)
+uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr)
 {
-return bus->config_readw(d, addr);
+return d->bus->config_readw(d, addr);
 }
 
-uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
-uint64_t addr)
+uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr)
 {
-return bus->config_readl(d, addr);
+return d->bus->config_readl(d, addr);
 }
 
-uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
-uint64_t addr)
+uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr)
 {
-return bus->config_readq(d, addr);
+return d->bus->config_readq(d, addr);
 }
 
-uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d)
+uint32_t qvirtio_get_features(QVirtioDevice *d)
 {
-return bus->get_features(d);
+return d->bus->get_features(d);
 }
 
-void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
-uint32_t features)
+void qvirtio_set_features(QVirtioDevice *d, uint32_t features)
 {
-bus->set_features(d, features);
+d->bus->set_features(d, features);
 }
 
-QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
-QGuestAllocator *alloc, uint16_t index)
+QVirtQueue *qvirtqueue_setup(QVirtioDevice *d,
+ QGuestAllocator *alloc, uint16_t index)
 {
-return bus->virtqueue_setup(d, alloc, index);
+return d->bus->virtqueue_setup(d, alloc, index);
 }
 
 void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
@@ -60,40 +55,40 @@ void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue 
*vq,
 return bus->virtqueue_cleanup(vq, alloc);
 }
 
-void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d)
+void qvirtio_reset(QVirtioDevice *d)
 {
-bus->set_status(d, 0);
-g_assert_cmphex(bus->get_status(d), ==, 0);
+d->bus->set_status(d, 0);
+g_assert_cmphex(d->bus->get_status(d), ==, 0);
 }
 
-void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d)
+void qvirtio_set_acknowledge(QVirtioDevice *d)
 {
-bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_ACKNOWLEDGE);
-g_assert_cmphex(bus->get_status(d), ==, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+g_assert_cmphex(d->bus->get_status(d), ==, 

Re: [Qemu-devel] [PATCH v2 5/6] target-ppc: add vprtyb[w/d/q] instructions

2016-10-27 Thread David Gibson
On Thu, Oct 27, 2016 at 07:16:24AM -0700, Richard Henderson wrote:
> On 10/27/2016 01:36 AM, Nikunj A Dadhania wrote:
> > Right, it does reduce number of operations:
> > 
> > +#define SIZE_MASK(x) ((1ULL << (x)) - 1)
> > +static uint64_t vparity(uint64_t f1, uint64_t f2, int size)
> > +{
> > +uint64_t res = f1 ^ f2;
> > +if (size == 8) return res;
> > +return vparity(res & SIZE_MASK(size/2), res >> (size/2), size/2);
> > +}
> 
> Why are you using recursion for something that should be 5 operations?
> You're making this more complicated than it needs to be.
> 
>   uint64_t res = b->u64[0] ^ b->u64[1];
>   res ^= res >> 32;
>   res ^= res >> 16;
>   res ^= res >> 8;
>   r->u64[LO_IDX] = res & 1;

We do need to implement it at multiple sizes, which makes it a bit
more complex.  But I wonder if it makes sense to do this without a
helper, something like

gen_vprty()
{
...
gen(shift right 8)
gen(xor)
if (size > 2)
   gen(shift right 16)
   gen(xor)
if (size > 4)
   gen(shift right 32)
   gen(xor)
if (size > 8)
   gen(xor hi and low words)
gen(mask result bits)
}

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v5 11/17] ppc/xics: Add "native" XICS subclass

2016-10-27 Thread David Gibson
On Thu, Oct 27, 2016 at 07:43:10PM +0200, Cédric Le Goater wrote:
> On 10/27/2016 05:09 AM, David Gibson wrote:
> > On Wed, Oct 26, 2016 at 09:13:18AM +0200, Cédric Le Goater wrote:
> >> On 10/25/2016 07:08 AM, David Gibson wrote:
> >>> On Sat, Oct 22, 2016 at 11:46:44AM +0200, Cédric Le Goater wrote:
>  This provides access to the MMIO based Interrupt Presentation
>  Controllers (ICP) as found on a POWER8 system.
> 
>  A new XICSNative class is introduced to hold the MMIO region of the
>  ICPs. Each thread of the system has a subregion, indexed by its PIR
>  number, holding a XIVE (External Interrupt Vector Entry). This
>  provides a mean to make the link with the ICPState of the CPU.
> 
>  Signed-off-by: Cédric Le Goater 
>  ---
> 
>   Changes since v4:
> 
>   - replaced the pir_able by memory subregions using an ICP. 
>   - removed the find_icp() and cpu_setup() handlers which became
> useless with the memory regions.
>   - removed the superfluous inits done in xics_native_initfn. This is
> covered in the parent class init.
>   - took ownership of the patch.
> 
>   default-configs/ppc64-softmmu.mak |   3 +-
>   hw/intc/Makefile.objs |   1 +
>   hw/intc/xics_native.c | 304 
>  ++
>   include/hw/ppc/pnv.h  |  19 +++
>   include/hw/ppc/xics.h |  24 +++
>   5 files changed, 350 insertions(+), 1 deletion(-)
>   create mode 100644 hw/intc/xics_native.c
> 
>  diff --git a/default-configs/ppc64-softmmu.mak 
>  b/default-configs/ppc64-softmmu.mak
>  index 67a9bcaa67fa..a22c93a48686 100644
>  --- a/default-configs/ppc64-softmmu.mak
>  +++ b/default-configs/ppc64-softmmu.mak
>  @@ -48,8 +48,9 @@ CONFIG_PLATFORM_BUS=y
>   CONFIG_ETSEC=y
>   CONFIG_LIBDECNUMBER=y
>   # For pSeries
>  -CONFIG_XICS=$(CONFIG_PSERIES)
>  +CONFIG_XICS=$(or $(CONFIG_PSERIES),$(CONFIG_POWERNV))
>   CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
>  +CONFIG_XICS_NATIVE=$(CONFIG_POWERNV)
>   CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
>   # For PReP
>   CONFIG_MC146818RTC=y
>  diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
>  index 2f44a2da26e9..e44a29d75b32 100644
>  --- a/hw/intc/Makefile.objs
>  +++ b/hw/intc/Makefile.objs
>  @@ -34,6 +34,7 @@ obj-$(CONFIG_RASPI) += bcm2835_ic.o bcm2836_control.o
>   obj-$(CONFIG_SH4) += sh_intc.o
>   obj-$(CONFIG_XICS) += xics.o
>   obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
>  +obj-$(CONFIG_XICS_NATIVE) += xics_native.o
>   obj-$(CONFIG_XICS_KVM) += xics_kvm.o
>   obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
>   obj-$(CONFIG_S390_FLIC) += s390_flic.o
>  diff --git a/hw/intc/xics_native.c b/hw/intc/xics_native.c
>  new file mode 100644
>  index ..bbdd786aeb50
>  --- /dev/null
>  +++ b/hw/intc/xics_native.c
>  @@ -0,0 +1,304 @@
>  +/*
>  + * QEMU PowerPC PowerNV machine model
>  + *
>  + * Native version of ICS/ICP
>  + *
>  + * Copyright (c) 2016, IBM Corporation.
>  + *
>  + * This library is free software; you can redistribute it and/or
>  + * modify it under the terms of the GNU Lesser General Public
>  + * License as published by the Free Software Foundation; either
>  + * version 2 of the License, or (at your option) any later version.
>  + *
>  + * This library is distributed in the hope that it will be useful,
>  + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>  + * Lesser General Public License for more details.
>  + *
>  + * You should have received a copy of the GNU Lesser General Public
>  + * License along with this library; if not, see 
>  .
>  + */
>  +
>  +#include "qemu/osdep.h"
>  +#include "qapi/error.h"
>  +#include "qemu-common.h"
>  +#include "cpu.h"
>  +#include "hw/hw.h"
>  +#include "qemu/log.h"
>  +#include "qapi/error.h"
>  +
>  +#include "hw/ppc/fdt.h"
>  +#include "hw/ppc/xics.h"
>  +#include "hw/ppc/pnv.h"
>  +
>  +#include 
>  +
>  +static void xics_native_reset(void *opaque)
>  +{
>  +device_reset(DEVICE(opaque));
>  +}
>  +
>  +static void xics_native_initfn(Object *obj)
>  +{
>  +qemu_register_reset(xics_native_reset, obj);
>  +}
> >>>
> >>> I think we need to investigate why the xics native is not showing up
> >>> on the SysBus.  As a "raw" MMIO device, it really should. 
> >>
> >> Well, it has sysbus mmio region, but it is not created with 
> >> qdev_create(...) 
> >> so it is not under sysbus and the reset does not get called. That is my
> >> understanding of the problem.
> >>
> 

Re: [Qemu-devel] [PATCH v5 13/17] ppc/xics: add a xics_get_cpu_index_by_pir helper

2016-10-27 Thread David Gibson
On Thu, Oct 27, 2016 at 08:05:02PM +0200, Cédric Le Goater wrote:
> On 10/27/2016 05:12 AM, David Gibson wrote:
> > On Tue, Oct 25, 2016 at 12:58:11PM +0200, Cédric Le Goater wrote:
> >> On 10/25/2016 07:36 AM, David Gibson wrote:
> >>> On Sat, Oct 22, 2016 at 11:46:46AM +0200, Cédric Le Goater wrote:
>  We will need this helper to translate the server number of the XIVE
>  (which is a PIR) into an ICPState index number (which is a cpu index).
> 
>  Signed-off-by: Cédric Le Goater 
> >>>
> >>> Looks correct as far as it goes, but I wonder if this would be more
> >>> generally useful as a machine level function that searches the cpu
> >>> objects by PIR, returning a pointer.  From that to the cpu_index is
> >>> then trivial.
> >>
> >> Well I guess so. The XICSState argument reduces the scope in case of 
> >> multichip but as this routine is used to initialize the xive registers, 
> >> it does not need to be fast.
> > 
> > Ahh.. I was thinking of the top-level xics object as global, rather
> > than per-chip.
> 
> well, the ICP MMIO region address is linked to the chip but that is all
> for the moment.
>  
> > Except.. does having it per-chip work anyway? The server numbers are 
> > globally unique, aren't they?  
> 
> yes.
>  
> > What happens if you put a server number from one chip as the target 
> > for an ICE on another chip?
> 
> we have the chip number, so we could route ? I haven't gone that far
> in the modeling though. It might be overly complex to do for the purpose.

Right.. yeah, trying to route between XICS objects sounds like a
nightmare.  Really the whole notion of the XICS overall object is that
it represents the whole irq propagation fabric - so it knows about all
the ICPS and all the ICSes and handles the routing between them.

So making the XICS object per-chip I think is a mistake which will
just lead to pain down the track.  See my other mail for a new
suggestion on how to handle this.

> > The xics object is a bit weird, in that it doesn't represent a real
> > device in a sense, but is rather something to co-ordinate global
> > addressing between ICS and ICP units.  Well, I suppose in that sense
> > it represent the interrupt propagation fabric.
> 
> yes. See my other email. I think we can get rid of it and simply use
> a XICSState which links together the ICPs and the ICS of the system. 
> but, let's keep it at the chip level for the moment, it is correct, 
> and see if we need to move it upwards when we work on multichip.

No, I disagree.  I think moving the XICs up a layer will only create
pain later for little benefit now.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto device specification

2016-10-27 Thread Gonglei (Arei)
> From: Michael S. Tsirkin [mailto:m...@redhat.com]
> Sent: Friday, October 28, 2016 9:13 AM
> To: Gonglei (Arei)
> Subject: Re: [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto 
> device
> specification
> 
> On Fri, Oct 28, 2016 at 01:01:40AM +, Gonglei (Arei) wrote:
> >
> > > -Original Message-
> > > From: virtio-...@lists.oasis-open.org
> [mailto:virtio-...@lists.oasis-open.org]
> > > On Behalf Of Michael S. Tsirkin
> > > Sent: Friday, October 28, 2016 6:14 AM
> > > Subject: [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto 
> > > device
> > > specification
> > >
> > > On Mon, Oct 24, 2016 at 06:51:52AM +, Gonglei (Arei) wrote:
> > > > Ping
> > > >
> > > > And the corresponding source code v9 on QEMU side had been posted:
> > > >
> > > > [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
> > > >  https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04755.html
> > > >
> > > > Regards,
> > > > -Gonglei
> > >
> > > If there are no comments and this is ready to get votes now,
> > > pls open the jira issue that you created.
> > > I can then start the ballot.
> > >
> > OK, I see. Thanks!
> >
> > I'd like to add max_size in the device config as you mentioned in other 
> > thread,
> > and submit v13 as the final version if not other comments.
> > And then open the jira issue.
> >
> >
> > Regards,
> > -Gonglei
> 
> Sounds good. So pls post this ASAP and give poeple
> a week to review before opening.
> 
OK.

> It's a good idea to go over the driver
> and see whether there are other limits that need to
> be set to limit resource utilization by guest, if yes
> add those - you are a better judge of this.
> 
Yep, I'll recheck them. Thanks.


Regards,
-Gonglei



Re: [Qemu-devel] [PATCH v2 0/2] memory: Convert skip_dump to ram_device and avoid memcpy

2016-10-27 Thread Thorsten Kohfeldt

I tested these
https://lists.nongnu.org/archive/html/qemu-devel/2016-10/msg05900.html
https://lists.nongnu.org/archive/html/qemu-devel/2016-10/msg05901.html
https://lists.nongnu.org/archive/html/qemu-devel/2016-10/msg05902.html

together with [Qemu-devel] [PULL 18/19] vfio/pci: Fix 
vfio_rtl8168_quirk_data_read add
https://lists.nongnu.org/archive/html/qemu-devel/2016-10/msg03911.html

on top of qemu-stable-2.7.0

successfully on IPFire (Linux) and Windows 10 x64 with the Realtek driver.

I suggest all 3 commits (msg05901, msg05902, and msg03911) should become
serious candidates for qemu-2.7.1.

Regards,

Thorsten

Am 25.10.2016 um 20:17 schrieb Alex Williamson:

v2: retain ram_device flag to avoid extra cache miss, per Paolo.

Paolo, posting for completeness, I can merge through my tree if you
want to Ack.  Thanks,

Alex

---

Alex Williamson (2):
  memory: Replace skip_dump flag with "ram_device"
  memory: Don't use memcpy for ram_device regions


 hw/vfio/common.c  |9 ++
 hw/vfio/spapr.c   |2 +
 include/exec/memory.h |   47 -
 memory.c  |   80 +++--
 memory_mapping.c  |2 +
 trace-events  |2 +
 6 files changed, 116 insertions(+), 26 deletions(-)





Re: [Qemu-devel] [PATCH] tests: Remove unneeded "-vnc none" option

2016-10-27 Thread Michael S. Tsirkin
On Mon, Oct 24, 2016 at 02:25:49PM -0200, Eduardo Habkost wrote:
> Some tests use the "-vnc none" option without any clear reason,
> making those tests break when --disable-vnc is specified on
> ./configure.  Remove the unnecessary option.
> 
> Signed-off-by: Eduardo Habkost 

FWIW

Reviewed-by: Michael S. Tsirkin 

> ---
>  tests/ide-test.c  | 1 -
>  tests/ipmi-bt-test.c  | 2 +-
>  tests/ipmi-kcs-test.c | 2 +-
>  3 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/tests/ide-test.c b/tests/ide-test.c
> index a8a4081..3fbcb75 100644
> --- a/tests/ide-test.c
> +++ b/tests/ide-test.c
> @@ -582,7 +582,6 @@ static void test_retry_flush(const char *machine)
>  prepare_blkdebug_script(debug_path, "flush_to_disk");
>  
>  ide_test_start(
> -"-vnc none "
>  "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
>  "rerror=stop,werror=stop",
>  debug_path, tmp_path);
> diff --git a/tests/ipmi-bt-test.c b/tests/ipmi-bt-test.c
> index be9005e..ad1e97e 100644
> --- a/tests/ipmi-bt-test.c
> +++ b/tests/ipmi-bt-test.c
> @@ -415,7 +415,7 @@ int main(int argc, char **argv)
>  /* Run the tests */
>  g_test_init(, , NULL);
>  
> -cmdline = g_strdup_printf("-vnc none"
> +cmdline = g_strdup_printf(
>" -chardev socket,id=ipmi0,host=localhost,port=%d,reconnect=10"
>" -device ipmi-bmc-extern,chardev=ipmi0,id=bmc0"
>" -device isa-ipmi-bt,bmc=bmc0", emu_port);
> diff --git a/tests/ipmi-kcs-test.c b/tests/ipmi-kcs-test.c
> index 3750389..9cf0b34 100644
> --- a/tests/ipmi-kcs-test.c
> +++ b/tests/ipmi-kcs-test.c
> @@ -276,7 +276,7 @@ int main(int argc, char **argv)
>  /* Run the tests */
>  g_test_init(, , NULL);
>  
> -cmdline = g_strdup_printf("-vnc none -device ipmi-bmc-sim,id=bmc0"
> +cmdline = g_strdup_printf("-device ipmi-bmc-sim,id=bmc0"
>" -device isa-ipmi-kcs,bmc=bmc0");
>  qtest_start(cmdline);
>  qtest_irq_intercept_in(global_qtest, "ioapic");
> -- 
> 2.7.4



Re: [Qemu-devel] [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto device specification

2016-10-27 Thread Michael S. Tsirkin
On Fri, Oct 28, 2016 at 01:01:40AM +, Gonglei (Arei) wrote:
> 
> > -Original Message-
> > From: virtio-...@lists.oasis-open.org 
> > [mailto:virtio-...@lists.oasis-open.org]
> > On Behalf Of Michael S. Tsirkin
> > Sent: Friday, October 28, 2016 6:14 AM
> > Subject: [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto 
> > device
> > specification
> > 
> > On Mon, Oct 24, 2016 at 06:51:52AM +, Gonglei (Arei) wrote:
> > > Ping
> > >
> > > And the corresponding source code v9 on QEMU side had been posted:
> > >
> > > [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
> > >  https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04755.html
> > >
> > > Regards,
> > > -Gonglei
> > 
> > If there are no comments and this is ready to get votes now,
> > pls open the jira issue that you created.
> > I can then start the ballot.
> > 
> OK, I see. Thanks!
> 
> I'd like to add max_size in the device config as you mentioned in other 
> thread,
> and submit v13 as the final version if not other comments.
> And then open the jira issue.
> 
> 
> Regards,
> -Gonglei

Sounds good. So pls post this ASAP and give poeple
a week to review before opening.

It's a good idea to go over the driver
and see whether there are other limits that need to
be set to limit resource utilization by guest, if yes
add those - you are a better judge of this.

-- 
MST



Re: [Qemu-devel] [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto device specification

2016-10-27 Thread Gonglei (Arei)

> -Original Message-
> From: virtio-...@lists.oasis-open.org [mailto:virtio-...@lists.oasis-open.org]
> On Behalf Of Michael S. Tsirkin
> Sent: Friday, October 28, 2016 6:14 AM
> Subject: [virtio-dev] Re: [PATCH v12 0/2] virtio-crypto: virtio crypto device
> specification
> 
> On Mon, Oct 24, 2016 at 06:51:52AM +, Gonglei (Arei) wrote:
> > Ping
> >
> > And the corresponding source code v9 on QEMU side had been posted:
> >
> > [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
> >  https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04755.html
> >
> > Regards,
> > -Gonglei
> 
> If there are no comments and this is ready to get votes now,
> pls open the jira issue that you created.
> I can then start the ballot.
> 
OK, I see. Thanks!

I'd like to add max_size in the device config as you mentioned in other thread,
and submit v13 as the final version if not other comments.
And then open the jira issue.


Regards,
-Gonglei



Re: [Qemu-devel] [virtio-dev] Re: [PATCH v9 09/12] virtio-crypto: add data queue processing handler

2016-10-27 Thread Gonglei (Arei)
Hi Michael,

Thanks for your comments.

> -Original Message-
> From: virtio-...@lists.oasis-open.org [mailto:virtio-...@lists.oasis-open.org]
> On Behalf Of Michael S. Tsirkin
> Sent: Friday, October 28, 2016 12:59 AM
> Subject: [virtio-dev] Re: [PATCH v9 09/12] virtio-crypto: add data queue
> processing handler
> 
> On Thu, Oct 20, 2016 at 07:45:54PM +0800, Gonglei wrote:
> > Introduces VirtIOCryptoReq structure to store
> > crypto request so that we can easily support
> > asynchronous crypto operation in the future.
> >
> > At present, we only support cipher and algorithm
> > chaining.
> >
> > Signed-off-by: Gonglei 
> > ---
> >  hw/virtio/virtio-crypto.c | 358
> +-
> >  include/hw/virtio/virtio-crypto.h |   4 +
> >  2 files changed, 361 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> > index 4be65e0..eabc61f 100644
> > --- a/hw/virtio/virtio-crypto.c
> > +++ b/hw/virtio/virtio-crypto.c
> > @@ -311,6 +311,362 @@ static void virtio_crypto_handle_ctrl(VirtIODevice
> *vdev, VirtQueue *vq)
> >  } /* end for loop */
> >  }
> >
> > +static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue 
> > *vq,
> > +VirtIOCryptoReq *req)
> > +{
> > +req->vcrypto = vcrypto;
> > +req->vq = vq;
> > +req->in = NULL;
> > +req->in_iov = NULL;
> > +req->in_num = 0;
> > +req->in_len = 0;
> > +req->flags = CRYPTODEV_BACKEND_ALG__MAX;
> > +req->u.sym_op_info = NULL;
> > +}
> > +
> > +static void virtio_crypto_free_request(VirtIOCryptoReq *req)
> > +{
> > +if (req) {
> > +if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
> > +g_free(req->u.sym_op_info);
> > +}
> > +g_free(req);
> > +}
> > +}
> > +
> > +static void
> > +virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
> > +VirtIOCryptoReq *req,
> > +uint32_t status,
> > +CryptoDevBackendSymOpInfo *sym_op_info)
> > +{
> > +size_t s, len;
> > +
> > +if (status != VIRTIO_CRYPTO_OK) {
> > +return;
> > +}
> > +
> > +len = sym_op_info->dst_len;
> > +/* Save the cipher result */
> > +s = iov_from_buf(req->in_iov, req->in_num, 0, sym_op_info->dst, len);
> > +if (s != len) {
> > +virtio_error(vdev, "virtio-crypto dest data incorrect");
> > +return;
> > +}
> > +
> > +iov_discard_front(>in_iov, >in_num, len);
> > +
> > +if (sym_op_info->op_type ==
> > +
> VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
> > +/* Save the digest result */
> > +s = iov_from_buf(req->in_iov, req->in_num, 0,
> > + sym_op_info->digest_result,
> > + sym_op_info->digest_result_len);
> > +if (s != sym_op_info->digest_result_len) {
> > +virtio_error(vdev, "virtio-crypto digest result incorrect");
> > +}
> > +}
> > +}
> > +
> > +static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint8_t
> status)
> > +{
> > +VirtIOCrypto *vcrypto = req->vcrypto;
> > +VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
> > +
> > +if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
> > +virtio_crypto_sym_input_data_helper(vdev, req, status,
> > +req->u.sym_op_info);
> > +}
> > +stb_p(>in->status, status);
> > +virtqueue_push(req->vq, >elem, req->in_len);
> > +virtio_notify(vdev, req->vq);
> > +}
> > +
> > +static VirtIOCryptoReq *
> > +virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
> > +{
> > +VirtIOCryptoReq *req = virtqueue_pop(vq, sizeof(VirtIOCryptoReq));
> > +
> > +if (req) {
> > +virtio_crypto_init_request(s, vq, req);
> > +}
> > +return req;
> > +}
> > +
> > +static CryptoDevBackendSymOpInfo *
> > +virtio_crypto_sym_op_helper(VirtIODevice *vdev,
> > +   struct virtio_crypto_cipher_para *cipher_para,
> > +   struct virtio_crypto_alg_chain_data_para *alg_chain_para,
> > +   struct iovec *iov, unsigned int out_num)
> > +{
> > +CryptoDevBackendSymOpInfo *op_info;
> > +uint32_t src_len = 0, dst_len = 0;
> > +uint32_t iv_len = 0;
> > +uint32_t aad_len = 0, hash_result_len = 0;
> > +uint32_t hash_start_src_offset = 0, len_to_hash = 0;
> > +uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
> > +
> > +size_t max_len, curr_size = 0;
> > +size_t s;
> > +
> > +/* Plain cipher */
> > +if (cipher_para) {
> > +iv_len = virtio_ldl_p(vdev, _para->iv_len);
> > +src_len = virtio_ldl_p(vdev, _para->src_data_len);
> > +dst_len = virtio_ldl_p(vdev, _para->dst_data_len);
> > +} else if (alg_chain_para) { /* Algorithm chain */
> > +iv_len = virtio_ldl_p(vdev, _chain_para->iv_len);
> > +src_len = virtio_ldl_p(vdev, _chain_para->src_data_len);
> > +dst_len = 

Re: [Qemu-devel] [PATCH] fixup! pc: add 'etc/boot-cpus' fw_cfg file for machine with more than 255 CPUs

2016-10-27 Thread Eduardo Habkost
On Fri, Oct 28, 2016 at 01:08:32AM +0300, Michael S. Tsirkin wrote:
> On Fri, Oct 21, 2016 at 10:53:27AM +0200, Igor Mammedov wrote:
> > On Thu, 20 Oct 2016 16:51:48 -0200
> > Eduardo Habkost  wrote:
> > 
> > > On Thu, Oct 20, 2016 at 04:58:42PM +0200, Igor Mammedov wrote:
> > > > Currently firmware uses 1 byte at 0x5F offset in RTC CMOS
> > > > to get number of CPUs present at boot. However 1 byte is
> > > > not enough to handle more than 255 CPUs.  So add a new
> > > > fw_cfg file that would allow QEMU to tell it.
> > > > For compat reasons add file only for machine types that
> > > > support more than 255 CPUs.
> > > > 
> > > > Signed-off-by: Igor Mammedov   
> > > 
> > > I suggest squashing this into the patch, to clarify why we are
> > > setting it to 0.
> > > 
> > > Signed-off-by: Eduardo Habkost 
> > 
> > Could you squash it in while merging series?
> 
> I'm not sure who's merging it (Eduardo do you want to?)
> if me, I'd rather  see a clean repost, with a squash and acks
> included.

It's already merged. See commit
080ac219cc7d9c55adf925c3545b7450055ad625.

-- 
Eduardo



[Qemu-devel] [PATCH] tcg: correct 32-bit tcg_gen_ld8s_i64 sign-extension

2016-10-27 Thread Joseph Myers
The version of tcg_gen_ld8s_i64 for 32-bit systems does a load into
the low part of the return value - then attempts a sign extension into
the high part, but wrongly sets the high part to a sign extension of
itself rather than of the low part.  This results in TCG internal
errors from the use of the uninitialized high part (in some GCC tests
of AArch64 NEON shift intrinsics, in particular).  This patch corrects
the sign-extension logic, making it match other functions such as
tcg_gen_ld16s_i64.

Signed-off-by: Joseph Myers 

---

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index bb2bfee..43d34ea 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -790,7 +790,7 @@ void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, 
tcg_target_long offset)
 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
 {
 tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
-tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31);
+tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
 }
 
 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)

-- 
Joseph S. Myers
jos...@codesourcery.com



Re: [Qemu-devel] [PATCH v2 6/8] loader: Support Flattened Image Trees (FIT images)

2016-10-27 Thread Yongbok Kim


On 08/09/2016 15:51, Paul Burton wrote:
> Introduce support for loading Flattened Image Trees, as used by modern
> U-Boot. FIT images are essentially flattened device tree files which
> contain binary images such as kernels, FDTs or ramdisks along with one
> or more configuration nodes describing boot configurations.
> 
> The MIPS Boston board typically boots kernels in the form of FIT images,
> and will make use of this code.
> 
> Signed-off-by: Paul Burton 
> ---
>  hw/core/Makefile.objs   |   1 +
>  hw/core/loader-fit.c| 287 
> 
>  hw/core/loader.c|   3 +-
>  include/hw/loader-fit.h |  41 +++
>  include/hw/loader.h |   2 +
>  5 files changed, 332 insertions(+), 2 deletions(-)
>  create mode 100644 hw/core/loader-fit.c
>  create mode 100644 include/hw/loader-fit.h
> 
> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
> index cfd4840..4adb860 100644
> --- a/hw/core/Makefile.objs
> +++ b/hw/core/Makefile.objs
> @@ -14,6 +14,7 @@ common-obj-$(CONFIG_SOFTMMU) += sysbus.o
>  common-obj-$(CONFIG_SOFTMMU) += machine.o
>  common-obj-$(CONFIG_SOFTMMU) += null-machine.o
>  common-obj-$(CONFIG_SOFTMMU) += loader.o
> +common-obj-$(CONFIG_SOFTMMU) += loader-fit.o
>  common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
>  common-obj-$(CONFIG_SOFTMMU) += register.o
>  common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
> diff --git a/hw/core/loader-fit.c b/hw/core/loader-fit.c
> new file mode 100644
> index 000..479a7fb
> --- /dev/null
> +++ b/hw/core/loader-fit.c
> @@ -0,0 +1,287 @@
> +/*
> + * Flattened Image Tree loader.
> + *
> + * Copyright (c) 2016 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 
> .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "exec/address-spaces.h"
> +#include "exec/memory.h"
> +#include "hw/loader.h"
> +#include "hw/loader-fit.h"
> +#include "qemu/cutils.h"
> +#include "qemu/error-report.h"
> +#include "sysemu/device_tree.h"
> +#include "sysemu/sysemu.h"
> +
> +#include 
> +#include 
> +
> +static const void *fit_load_image(const void *itb, const char *name,
> +  int *poff, size_t *psz)
> +{
> +const void *data;
> +const char *comp;
> +void *uncomp_data;
> +char path[128];
> +int off, sz;
> +ssize_t uncomp_len;
> +
> +snprintf(path, sizeof(path), "/images/%s", name);
> +
> +off = fdt_path_offset(itb, path);
> +if (off < 0) {
> +return NULL;
> +}
> +if (poff) {
> +*poff = off;
> +}
> +
> +data = fdt_getprop(itb, off, "data", );
> +if (!data) {
> +return NULL;
> +}
> +
> +comp = fdt_getprop(itb, off, "compression", NULL);
> +if (!comp || !strcmp(comp, "none")) {
> +if (psz) {
> +*psz = sz;
> +}
> +return data;
> +}
> +
> +if (!strcmp(comp, "gzip")) {
> +uncomp_len = 64 << 20;

Magic number. Perhaps UBOOT_MAX_GUNZIP_BYTES which is defined in the
loader.c? It would be better to move the definition to the loader.h and
reuse it here.

> +uncomp_data = g_malloc(uncomp_len);
> +
> +uncomp_len = gunzip(uncomp_data, uncomp_len, (void *)data, sz);
> +if (uncomp_len < 0) {
> +error_printf("unable to decompress %s image\n", name);
> +g_free(uncomp_data);
> +return NULL;
> +}
> +
> +data = g_realloc(uncomp_data, uncomp_len);
> +if (psz) {
> +*psz = uncomp_len;
> +}
> +return data;
> +}
> +
> +error_printf("unknown compression '%s'\n", comp);
> +return NULL;
> +}
> +
> +static int fit_image_addr(const void *itb, int img, const char *name,
> +  hwaddr *addr)
> +{
> +const void *prop;
> +int len;
> +
> +prop = fdt_getprop(itb, img, name, );
> +if (!prop) {
> +return -ENOENT;
> +}
> +
> +switch (len) {
> +case 4:
> +*addr = fdt32_to_cpu(*(fdt32_t *)prop);
> +return 0;
> +case 8:
> +*addr = fdt64_to_cpu(*(fdt64_t *)prop);
> +return 0;
> +default:
> +error_printf("invalid %s address length %d\n", name, len);
> +return -EINVAL;
> +}
> +}
> +
> +static int fit_load_kernel(const struct fit_loader *ldr, const void 

Re: [Qemu-devel] [PATCH v10 09/19] vfio iommu type1: Add support for mediated devices

2016-10-27 Thread Alex Williamson
On Thu, 27 Oct 2016 02:59:16 +0530
Kirti Wankhede  wrote:

> VFIO IOMMU drivers are designed for the devices which are IOMMU capable.
> Mediated device only uses IOMMU APIs, the underlying hardware can be
> managed by an IOMMU domain.
> 
> Aim of this change is:
> - To use most of the code of TYPE1 IOMMU driver for mediated devices
> - To support direct assigned device and mediated device in single module
> 
> This change adds pin and unpin support for mediated device to TYPE1 IOMMU
> backend module. More details:
> - When iommu_group of mediated devices is attached, task structure is
>   cached which is used later to pin pages and page accounting.
> - It keeps track of pinned pages for mediated domain. This data is used to
>   verify unpinning request and to unpin remaining pages while detaching, if
>   there are any.
> - Used existing mechanism for page accounting. If iommu capable domain
>   exist in the container then all pages are already pinned and accounted.
>   Accouting for mdev device is only done if there is no iommu capable
>   domain in the container.
> - Page accouting is updated on hot plug and unplug mdev device and pass
>   through device.
> 
> Tested by assigning below combinations of devices to a single VM:
> - GPU pass through only
> - vGPU device only
> - One GPU pass through and one vGPU device
> - Linux VM hot plug and unplug vGPU device while GPU pass through device
>   exist
> - Linux VM hot plug and unplug GPU pass through device while vGPU device
>   exist
> 
> Signed-off-by: Kirti Wankhede 
> Signed-off-by: Neo Jia 
> Change-Id: I295d6f0f2e0579b8d9882bfd8fd5a4194b97bd9a
> ---
>  drivers/vfio/vfio_iommu_type1.c | 646 
> +++-
>  1 file changed, 571 insertions(+), 75 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 861ac2a1b0c3..5add11a147e1 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -36,6 +36,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #define DRIVER_VERSION  "0.2"
>  #define DRIVER_AUTHOR   "Alex Williamson "
> @@ -55,18 +56,26 @@ MODULE_PARM_DESC(disable_hugepages,
>  
>  struct vfio_iommu {
>   struct list_headdomain_list;
> + struct vfio_domain  *external_domain; /* domain for external user */
>   struct mutexlock;
>   struct rb_root  dma_list;
>   boolv2;
>   boolnesting;
>  };
>  
> +struct external_addr_space {
> + struct task_struct  *task;
> + struct rb_root  pfn_list;   /* pinned Host pfn list */
> + struct mutexpfn_list_lock;  /* mutex for pfn_list */
> +};
> +
>  struct vfio_domain {
> - struct iommu_domain *domain;
> - struct list_headnext;
> - struct list_headgroup_list;
> - int prot;   /* IOMMU_CACHE */
> - boolfgsp;   /* Fine-grained super pages */
> + struct iommu_domain *domain;
> + struct list_headnext;
> + struct list_headgroup_list;
> + struct external_addr_space  *external_addr_space;
> + int prot;   /* IOMMU_CACHE */
> + boolfgsp;   /* Fine-grained super pages */
>  };
>  
>  struct vfio_dma {
> @@ -75,6 +84,7 @@ struct vfio_dma {
>   unsigned long   vaddr;  /* Process virtual addr */
>   size_t  size;   /* Map size (bytes) */
>   int prot;   /* IOMMU_READ/WRITE */
> + booliommu_mapped;
>  };
>  
>  struct vfio_group {
> @@ -83,6 +93,21 @@ struct vfio_group {
>  };
>  
>  /*
> + * Guest RAM pinning working set or DMA target
> + */
> +struct vfio_pfn {
> + struct rb_node  node;
> + unsigned long   vaddr;  /* virtual addr */
> + dma_addr_t  iova;   /* IOVA */
> + unsigned long   pfn;/* Host pfn */
> + int prot;
> + atomic_tref_count;
> +};
> +
> +#define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)  \
> + (!list_empty(>domain_list))
> +
> +/*
>   * This code handles mapping and unmapping of user data buffers
>   * into DMA'ble space using the IOMMU
>   */
> @@ -130,6 +155,101 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
> struct vfio_dma *old)
>   rb_erase(>node, >dma_list);
>  }
>  
> +/*
> + * Helper Functions for host pfn list
> + */
> +
> +static struct vfio_pfn *vfio_find_pfn(struct vfio_domain *domain,
> +   unsigned long pfn)
> +{
> + struct rb_node *node;
> + struct vfio_pfn *vpfn;
> +
> + node = 

[Qemu-devel] [QEMU PATCH v9 2/3] migration: migrate QTAILQ

2016-10-27 Thread Jianjun Duan
Currently we cannot directly transfer a QTAILQ instance because of the
limitation in the migration code. Here we introduce an approach to
transfer such structures. We created VMStateInfo vmstate_info_qtailq
for QTAILQ. Similar VMStateInfo can be created for other data structures
such as list.

This approach will be used to transfer pending_events and ccs_list in spapr
state.

We also create some macros in qemu/queue.h to access a QTAILQ using pointer
arithmetic. This ensures that we do not depend on the implementation
details about QTAILQ in the migration code.

Signed-off-by: Jianjun Duan 
---
 include/migration/vmstate.h | 20 ++
 include/qemu/queue.h| 61 +
 migration/trace-events  |  4 +++
 migration/vmstate.c | 67 +
 4 files changed, 152 insertions(+)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index d0e37b5..318a6f1 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -251,6 +251,7 @@ extern const VMStateInfo vmstate_info_timer;
 extern const VMStateInfo vmstate_info_buffer;
 extern const VMStateInfo vmstate_info_unused_buffer;
 extern const VMStateInfo vmstate_info_bitmap;
+extern const VMStateInfo vmstate_info_qtailq;
 
 #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
 #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0)
@@ -662,6 +663,25 @@ extern const VMStateInfo vmstate_info_bitmap;
 .offset   = offsetof(_state, _field),\
 }
 
+/* For QTAILQ that need customized handling.
+ * Target QTAILQ needs be properly initialized.
+ * _type: type of QTAILQ element
+ * _next: name of QTAILQ entry field in QTAILQ element
+ * _vmsd: VMSD for QTAILQ element
+ * size: size of QTAILQ element
+ * start: offset of QTAILQ entry in QTAILQ element
+ */
+#define VMSTATE_QTAILQ_V(_field, _state, _version, _vmsd, _type, _next)  \
+{\
+.name = (stringify(_field)), \
+.version_id   = (_version),  \
+.vmsd = &(_vmsd),\
+.size = sizeof(_type),   \
+.info = _info_qtailq,\
+.offset   = offsetof(_state, _field),\
+.start= offsetof(_type, _next),  \
+}
+
 /* _f : field name
_f_n : num of elements field_name
_n : num of elements
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 342073f..16af127 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -438,4 +438,65 @@ struct {   
 \
 #define QTAILQ_PREV(elm, headname, field) \
 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
 
+#define field_at_offset(base, offset, type)
\
+((type) (((char *) (base)) + (offset)))
+
+typedef struct DUMB_Q_ENTRY DUMB_Q_ENTRY;
+typedef struct DUMB_Q DUMB_Q;
+
+struct DUMB_Q_ENTRY {
+QTAILQ_ENTRY(DUMB_Q_ENTRY) next;
+};
+
+struct DUMB_Q {
+QTAILQ_HEAD(DUMB_Q_HEAD, DUMB_Q_ENTRY) head;
+};
+
+#define dumb_q ((DUMB_Q *) 0)
+#define dumb_qh ((typeof(dumb_q->head) *) 0)
+#define dumb_qe ((DUMB_Q_ENTRY *) 0)
+
+/*
+ * Offsets of layout of a tail queue head.
+ */
+#define QTAILQ_FIRST_OFFSET ((size_t) &(QTAILQ_FIRST(dumb_qh)))
+#define QTAILQ_LAST_OFFSET  (offsetof(typeof(dumb_q->head), tqh_last))
+/*
+ * Raw access of elements of a tail queue
+ */
+#define QTAILQ_RAW_FIRST(head) 
\
+(*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **))
+#define QTAILQ_RAW_LAST(head)  
\
+(*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***))
+
+/*
+ * Offsets of layout of a tail queue element.
+ */
+#define QTAILQ_NEXT_OFFSET ((size_t) (_NEXT(dumb_qe, next)))
+#define QTAILQ_PREV_OFFSET (offsetof(typeof(dumb_qe->next), tqe_prev))
+
+/*
+ * Raw access of elements of a tail entry
+ */
+#define QTAILQ_RAW_NEXT(elm, entry)
\
+(*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void **))
+#define QTAILQ_RAW_PREV(elm, entry)
\
+(*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void ***))
+/*
+ * Tail queue tranversal using pointer arithmetic.
+ */
+#define QTAILQ_RAW_FOREACH(elm, head, entry)   
\
+for ((elm) = QTAILQ_RAW_FIRST(head);   
\
+ (elm);
\
+ (elm) = QTAILQ_RAW_NEXT(elm, entry))
+/*
+ * Tail queue insertion using 

[Qemu-devel] [QEMU PATCH v9 1/3] migration: extend VMStateInfo

2016-10-27 Thread Jianjun Duan
Current migration code cannot handle some data structures such as
QTAILQ in qemu/queue.h. Here we extend the signatures of put/get
in VMStateInfo so that customized handling is supported.

Signed-off-by: Jianjun Duan 
---
 hw/display/virtio-gpu.c |   6 ++-
 hw/intc/s390_flic_kvm.c |   6 ++-
 hw/net/vmxnet3.c|  18 +---
 hw/nvram/eeprom93xx.c   |   6 ++-
 hw/nvram/fw_cfg.c   |   6 ++-
 hw/pci/msix.c   |   6 ++-
 hw/pci/pci.c|  12 +++--
 hw/pci/shpc.c   |   5 ++-
 hw/scsi/scsi-bus.c  |   6 ++-
 hw/timer/twl92230.c |   6 ++-
 hw/usb/redirect.c   |  18 +---
 hw/virtio/virtio-pci.c  |   6 ++-
 hw/virtio/virtio.c  |  12 +++--
 include/migration/vmstate.h |  15 +--
 migration/savevm.c  |   5 ++-
 migration/vmstate.c | 106 
 target-alpha/machine.c  |   5 ++-
 target-arm/machine.c|  12 +++--
 target-i386/machine.c   |  21 ++---
 target-mips/machine.c   |  10 +++--
 target-ppc/machine.c|  10 +++--
 target-sparc/machine.c  |   5 ++-
 22 files changed, 198 insertions(+), 104 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index fa6fd0e..2a21150 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -987,7 +987,8 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts 
= {
 },
 };
 
-static void virtio_gpu_save(QEMUFile *f, void *opaque, size_t size)
+static void virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
+VMStateField *field, QJSON *vmdesc)
 {
 VirtIOGPU *g = opaque;
 struct virtio_gpu_simple_resource *res;
@@ -1014,7 +1015,8 @@ static void virtio_gpu_save(QEMUFile *f, void *opaque, 
size_t size)
 vmstate_save_state(f, _virtio_gpu_scanouts, g, NULL);
 }
 
-static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size)
+static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
+   VMStateField *field)
 {
 VirtIOGPU *g = opaque;
 struct virtio_gpu_simple_resource *res;
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index 21ac2e2..a80a812 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -286,7 +286,8 @@ static void kvm_s390_release_adapter_routes(S390FLICState 
*fs,
  * increase until buffer is sufficient or maxium size is
  * reached
  */
-static void kvm_flic_save(QEMUFile *f, void *opaque, size_t size)
+static void kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
+  VMStateField *field, QJSON *vmdesc)
 {
 KVMS390FLICState *flic = opaque;
 int len = FLIC_SAVE_INITIAL_SIZE;
@@ -331,7 +332,8 @@ static void kvm_flic_save(QEMUFile *f, void *opaque, size_t 
size)
  * Note: Do nothing when no interrupts where stored
  * in QEMUFile
  */
-static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size)
+static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
+ VMStateField *field)
 {
 uint64_t len = 0;
 uint64_t count = 0;
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 90f6943..943a960 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2450,7 +2450,8 @@ static void vmxnet3_put_tx_stats_to_file(QEMUFile *f,
 qemu_put_be64(f, tx_stat->pktsTxDiscard);
 }
 
-static int vmxnet3_get_txq_descr(QEMUFile *f, void *pv, size_t size)
+static int vmxnet3_get_txq_descr(QEMUFile *f, void *pv, size_t size,
+VMStateField *field)
 {
 Vmxnet3TxqDescr *r = pv;
 
@@ -2464,7 +2465,8 @@ static int vmxnet3_get_txq_descr(QEMUFile *f, void *pv, 
size_t size)
 return 0;
 }
 
-static void vmxnet3_put_txq_descr(QEMUFile *f, void *pv, size_t size)
+static void vmxnet3_put_txq_descr(QEMUFile *f, void *pv, size_t size,
+VMStateField *field, QJSON *vmdesc)
 {
 Vmxnet3TxqDescr *r = pv;
 
@@ -2511,7 +2513,8 @@ static void vmxnet3_put_rx_stats_to_file(QEMUFile *f,
 qemu_put_be64(f, rx_stat->pktsRxError);
 }
 
-static int vmxnet3_get_rxq_descr(QEMUFile *f, void *pv, size_t size)
+static int vmxnet3_get_rxq_descr(QEMUFile *f, void *pv, size_t size,
+VMStateField *field)
 {
 Vmxnet3RxqDescr *r = pv;
 int i;
@@ -2529,7 +2532,8 @@ static int vmxnet3_get_rxq_descr(QEMUFile *f, void *pv, 
size_t size)
 return 0;
 }
 
-static void vmxnet3_put_rxq_descr(QEMUFile *f, void *pv, size_t size)
+static void vmxnet3_put_rxq_descr(QEMUFile *f, void *pv, size_t size,
+VMStateField *field, QJSON *vmdesc)
 {
 Vmxnet3RxqDescr *r = pv;
 int i;
@@ -2574,7 +2578,8 @@ static const VMStateInfo rxq_descr_info = {
 .put = vmxnet3_put_rxq_descr
 };
 
-static int vmxnet3_get_int_state(QEMUFile *f, void *pv, size_t size)
+static int vmxnet3_get_int_state(QEMUFile *f, void *pv, size_t size,
+VMStateField *field)
 {
 Vmxnet3IntState *r = pv;
 
@@ -2585,7 +2590,8 @@ static int vmxnet3_get_int_state(QEMUFile *f, 

  1   2   3   4   5   >