[PATCH v2] kvm: ppc: bookehv: Save restore SPRN_SPRG9 on guest entry exit

2014-07-20 Thread Bharat Bhushan
SPRN_SPRG is used by debug interrupt handler, so this is required for
debug support.

Signed-off-by: Bharat Bhushan 
---
v1->v2
 - sprng9 is 64bit, not 32bit

 arch/powerpc/include/asm/kvm_host.h   | 1 +
 arch/powerpc/kernel/asm-offsets.c | 1 +
 arch/powerpc/kvm/bookehv_interrupts.S | 4 
 3 files changed, 6 insertions(+)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 372b977..b3e370c 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -588,6 +588,7 @@ struct kvm_vcpu_arch {
u32 mmucfg;
u32 eptcfg;
u32 epr;
+   u64 sprg9;
u32 pwrmgtcr0;
u32 crit_save;
/* guest debug registers*/
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 17ffcb4..ab9ae04 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -668,6 +668,7 @@ int main(void)
DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
+   DEFINE(VCPU_SPRG9, offsetof(struct kvm_vcpu, arch.sprg9));
DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S 
b/arch/powerpc/kvm/bookehv_interrupts.S
index a1712b8..f45da85 100644
--- a/arch/powerpc/kvm/bookehv_interrupts.S
+++ b/arch/powerpc/kvm/bookehv_interrupts.S
@@ -441,6 +441,7 @@ _GLOBAL(kvmppc_resume_host)
 #ifdef CONFIG_64BIT
PPC_LL  r3, PACA_SPRG_VDSO(r13)
 #endif
+   mfspr   r5, SPRN_SPRG9
PPC_STD(r6, VCPU_SHARED_SPRG4, r11)
mfspr   r8, SPRN_SPRG6
PPC_STD(r7, VCPU_SHARED_SPRG5, r11)
@@ -448,6 +449,7 @@ _GLOBAL(kvmppc_resume_host)
 #ifdef CONFIG_64BIT
mtspr   SPRN_SPRG_VDSO_WRITE, r3
 #endif
+   PPC_STD(r5, VCPU_SPRG9, r4)
PPC_STD(r8, VCPU_SHARED_SPRG6, r11)
mfxer   r3
PPC_STD(r9, VCPU_SHARED_SPRG7, r11)
@@ -682,7 +684,9 @@ lightweight_exit:
mtspr   SPRN_SPRG5W, r6
PPC_LD(r8, VCPU_SHARED_SPRG7, r11)
mtspr   SPRN_SPRG6W, r7
+   PPC_LD(r5, VCPU_SPRG9, r4)
mtspr   SPRN_SPRG7W, r8
+   mtspr   SPRN_SPRG9, r5
 
/* Load some guest volatiles. */
PPC_LL  r3, VCPU_LR(r4)
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] docs: update ivshmem device spec

2014-07-20 Thread David Marchand
Add some notes on the parts needed to use ivshmem devices: more specifically,
explain the purpose of an ivshmem server and the basic concept to use the
ivshmem devices in guests.
Move some parts of the documentation and re-organise it.

Signed-off-by: David Marchand 
---
 docs/specs/ivshmem_device_spec.txt |  124 +++-
 1 file changed, 93 insertions(+), 31 deletions(-)

diff --git a/docs/specs/ivshmem_device_spec.txt 
b/docs/specs/ivshmem_device_spec.txt
index 667a862..f5f2b95 100644
--- a/docs/specs/ivshmem_device_spec.txt
+++ b/docs/specs/ivshmem_device_spec.txt
@@ -2,30 +2,103 @@
 Device Specification for Inter-VM shared memory device
 --
 
-The Inter-VM shared memory device is designed to share a region of memory to
-userspace in multiple virtual guests.  The memory region does not belong to any
-guest, but is a POSIX memory object on the host.  Optionally, the device may
-support sending interrupts to other guests sharing the same memory region.
+The Inter-VM shared memory device is designed to share a memory region (created
+on the host via the POSIX shared memory API) between multiple QEMU processes
+running different guests. In order for all guests to be able to pick up the
+shared memory area, it is modeled by QEMU as a PCI device exposing said memory
+to the guest as a PCI BAR.
+The memory region does not belong to any guest, but is a POSIX memory object on
+the host. The host can access this shared memory if needed.
+
+The device also provides an optional communication mechanism between guests
+sharing the same memory object. More details about that in the section 'Guest 
to
+guest communication' section.
 
 
 The Inter-VM PCI device
 ---
 
-*BARs*
+From the VM point of view, the ivshmem PCI device supports three BARs.
+
+- BAR0 is a 1 Kbyte MMIO region to support registers and interrupts when MSI is
+  not used.
+- BAR1 is used for MSI-X when it is enabled in the device.
+- BAR2 is used to access the shared memory object.
+
+It is your choice how to use the device but you must choose between two
+behaviors :
+
+- basically, if you only need the shared memory part, you will map BAR2.
+  This way, you have access to the shared memory in guest and can use it as you
+  see fit (memnic, for example, uses it in userland
+  http://dpdk.org/browse/memnic).
+
+- BAR0 and BAR1 are used to implement an optional communication mechanism
+  through interrupts in the guests. If you need an event mechanism between the
+  guests accessing the shared memory, you will most likely want to write a
+  kernel driver that will handle interrupts. See details in the section 'Guest
+  to guest communication' section.
+
+The behavior is chosen when starting your QEMU processes:
+- no communication mechanism needed, the first QEMU to start creates the shared
+  memory on the host, subsequent QEMU processes will use it.
+
+- communication mechanism needed, an ivshmem server must be started before any
+  QEMU processes, then each QEMU process connects to the server unix socket.
+
+For more details on the QEMU ivshmem parameters, see qemu-doc documentation.
+
+
+Guest to guest communication
+
+
+This section details the communication mechanism between the guests accessing
+the ivhsmem shared memory.
 
-The device supports three BARs.  BAR0 is a 1 Kbyte MMIO region to support
-registers.  BAR1 is used for MSI-X when it is enabled in the device.  BAR2 is
-used to map the shared memory object from the host.  The size of BAR2 is
-specified when the guest is started and must be a power of 2 in size.
+*ivshmem server*
 
-*Registers*
+This server code is available in qemu.git/contrib/ivshmem-server.
 
-The device currently supports 4 registers of 32-bits each.  Registers
-are used for synchronization between guests sharing the same memory object when
-interrupts are supported (this requires using the shared memory server).
+The server must be started on the host before any guest.
+It creates a shared memory object then waits for clients to connect on an unix
+socket.
 
-The server assigns each VM an ID number and sends this ID number to the QEMU
-process when the guest starts.
+For each client (QEMU processes) that connects to the server:
+- the server assigns an ID for this client and sends this ID to him as the 
first
+  message,
+- the server sends a fd to the shared memory object to this client,
+- the server creates a new set of host eventfds associated to the new client 
and
+  sends this set to all already connected clients,
+- finally, the server sends all the eventfds sets for all clients to the new
+  client.
+
+The server signals all clients when one of them disconnects.
+
+The client IDs are limited to 16 bits because of the current implementation 
(see
+Doorbell register in 'PCI device registers' subsection). Hence on 65536 clients
+are supported.
+
+All the file descriptors (fd to the share

[PATCH v2 1/2] contrib: add ivshmem client and server

2014-07-20 Thread David Marchand
When using ivshmem devices, notifications between guests can be sent as
interrupts using a ivshmem-server (typical use described in documentation).
The client is provided as a debug tool.

Signed-off-by: Olivier Matz 
Signed-off-by: David Marchand 
---
 contrib/ivshmem-client/Makefile |   26 ++
 contrib/ivshmem-client/ivshmem-client.c |  418 ++
 contrib/ivshmem-client/ivshmem-client.h |  238 ++
 contrib/ivshmem-client/main.c   |  246 ++
 contrib/ivshmem-server/Makefile |   26 ++
 contrib/ivshmem-server/ivshmem-server.c |  420 +++
 contrib/ivshmem-server/ivshmem-server.h |  185 ++
 contrib/ivshmem-server/main.c   |  296 ++
 qemu-doc.texi   |   10 +-
 9 files changed, 1862 insertions(+), 3 deletions(-)
 create mode 100644 contrib/ivshmem-client/Makefile
 create mode 100644 contrib/ivshmem-client/ivshmem-client.c
 create mode 100644 contrib/ivshmem-client/ivshmem-client.h
 create mode 100644 contrib/ivshmem-client/main.c
 create mode 100644 contrib/ivshmem-server/Makefile
 create mode 100644 contrib/ivshmem-server/ivshmem-server.c
 create mode 100644 contrib/ivshmem-server/ivshmem-server.h
 create mode 100644 contrib/ivshmem-server/main.c

diff --git a/contrib/ivshmem-client/Makefile b/contrib/ivshmem-client/Makefile
new file mode 100644
index 000..9e32409
--- /dev/null
+++ b/contrib/ivshmem-client/Makefile
@@ -0,0 +1,26 @@
+# Copyright 2014 6WIND S.A.
+# All rights reserved
+
+S ?= $(CURDIR)
+O ?= $(CURDIR)
+
+CFLAGS += -Wall -Wextra -Werror -g
+LDFLAGS +=
+LDLIBS += -lrt
+
+VPATH = $(S)
+PROG = ivshmem-client
+OBJS := $(O)/ivshmem-client.o
+OBJS += $(O)/main.o
+
+$(O)/%.o: %.c
+   $(CC) $(CFLAGS) -o $@ -c $<
+
+$(O)/$(PROG): $(OBJS)
+   $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+.PHONY: all
+all: $(O)/$(PROG)
+
+clean:
+   rm -f $(OBJS) $(O)/$(PROG)
diff --git a/contrib/ivshmem-client/ivshmem-client.c 
b/contrib/ivshmem-client/ivshmem-client.c
new file mode 100644
index 000..32ef3ef
--- /dev/null
+++ b/contrib/ivshmem-client/ivshmem-client.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright(c) 2014 6WIND S.A.
+ * All rights reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "ivshmem-client.h"
+
+/* log a message on stdout if verbose=1 */
+#define debug_log(client, fmt, ...) do { \
+if ((client)->verbose) { \
+printf(fmt, ## __VA_ARGS__); \
+}\
+} while (0)
+
+/* read message from the unix socket */
+static int
+read_one_msg(struct ivshmem_client *client, long *index, int *fd)
+{
+int ret;
+struct msghdr msg;
+struct iovec iov[1];
+union {
+struct cmsghdr cmsg;
+char control[CMSG_SPACE(sizeof(int))];
+} msg_control;
+struct cmsghdr *cmsg;
+
+iov[0].iov_base = index;
+iov[0].iov_len = sizeof(*index);
+
+memset(&msg, 0, sizeof(msg));
+msg.msg_iov = iov;
+msg.msg_iovlen = 1;
+msg.msg_control = &msg_control;
+msg.msg_controllen = sizeof(msg_control);
+
+ret = recvmsg(client->sock_fd, &msg, 0);
+if (ret < 0) {
+debug_log(client, "cannot read message: %s\n", strerror(errno));
+return -1;
+}
+if (ret == 0) {
+debug_log(client, "lost connection to server\n");
+return -1;
+}
+
+*fd = -1;
+
+for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+
+if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
+cmsg->cmsg_level != SOL_SOCKET ||
+cmsg->cmsg_type != SCM_RIGHTS) {
+continue;
+}
+
+memcpy(fd, CMSG_DATA(cmsg), sizeof(*fd));
+}
+
+return 0;
+}
+
+/* free a peer when the server advertise a disconnection or when the
+ * client is freed */
+static void
+free_peer(struct ivshmem_client *client, struct ivshmem_client_peer *peer)
+{
+unsigned vector;
+
+TAILQ_REMOVE(&client->peer_list, peer, next);
+for (vector = 0; vector < peer->vectors_count; vector++) {
+close(peer->vectors[vector]);
+}
+
+free(peer);
+}
+
+/* handle message coming from server (new peer, new vectors) */
+static int
+handle_server_msg(struct ivshmem_client *client)
+{
+struct ivshmem_client_peer *peer;
+long peer_id;
+int ret, fd;
+
+ret = read_one_msg(client, &peer_id, &fd);
+if (ret < 0) {
+return -1;
+}
+
+/* can return a peer or the local client */
+peer = ivshmem_client_search_peer(client, peer_id);
+
+/* delete peer */
+if (fd == -1) {
+
+if (peer == NULL || peer == &client->local) {
+debug_log(client, "receive delete for invalid peer %ld", peer_id);
+return

[PATCH v2 0/2] ivshmem: update documentation, add client/server tools

2014-07-20 Thread David Marchand
Here is a patchset containing an update on ivshmem specs documentation and
importing ivshmem server and client tools.
These tools have been written from scratch and are not related to what is
available in nahanni repository.
I put them in contrib/ directory as the qemu-doc.texi was already telling the
server was supposed to be there.

Changes since v1:
- moved client/server import patch before doc update,
- tried to re-organise the ivshmem_device_spec.txt file based on Claudio
  comments (still not sure if the result is that great, comments welcome),
- incorporated comments from Claudio, Eric and Cam,
- added more details on the server <-> client messages exchange (but sorry, no
  ASCII art here).

By the way, there are still some functionnalities that need description (use of
ioeventfd, the lack of irqfd support) and some parts of the ivshmem code clearly
need cleanup. I will try to address this in future patches when these first
patches are ok.


-- 
David Marchand

David Marchand (2):
  contrib: add ivshmem client and server
  docs: update ivshmem device spec

 contrib/ivshmem-client/Makefile |   26 ++
 contrib/ivshmem-client/ivshmem-client.c |  418 ++
 contrib/ivshmem-client/ivshmem-client.h |  238 ++
 contrib/ivshmem-client/main.c   |  246 ++
 contrib/ivshmem-server/Makefile |   26 ++
 contrib/ivshmem-server/ivshmem-server.c |  420 +++
 contrib/ivshmem-server/ivshmem-server.h |  185 ++
 contrib/ivshmem-server/main.c   |  296 ++
 docs/specs/ivshmem_device_spec.txt  |  124 ++---
 qemu-doc.texi   |   10 +-
 10 files changed, 1955 insertions(+), 34 deletions(-)
 create mode 100644 contrib/ivshmem-client/Makefile
 create mode 100644 contrib/ivshmem-client/ivshmem-client.c
 create mode 100644 contrib/ivshmem-client/ivshmem-client.h
 create mode 100644 contrib/ivshmem-client/main.c
 create mode 100644 contrib/ivshmem-server/Makefile
 create mode 100644 contrib/ivshmem-server/ivshmem-server.c
 create mode 100644 contrib/ivshmem-server/ivshmem-server.h
 create mode 100644 contrib/ivshmem-server/main.c

-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm-all: Use 'tmpcpu' instead of 'cpu' in sub-looping to avoid 'cpu' be NULL

2014-07-20 Thread Chen Gang
On 07/20/2014 03:29 PM, Jan Kiszka wrote:
> On 2014-07-19 03:21, Chen Gang wrote:
>> If kvm_arch_remove_sw_breakpoint() in CPU_FOREACH() always be fail, it
>> will let 'cpu' NULL. And the next kvm_arch_remove_sw_breakpoint() in
>> QTAILQ_FOREACH_SAFE() will get NULL parameter for 'cpu'.
>>
>> And kvm_arch_remove_sw_breakpoint() can assumes 'cpu' must never be NULL,
>> so need define additional temporary variable for 'cpu' to avoid the case.
>>
>>
>> Signed-off-by: Chen Gang 
>> ---
>>  kvm-all.c | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 3ae30ee..1402f4f 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -2077,12 +2077,13 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
>>  {
>>  struct kvm_sw_breakpoint *bp, *next;
>>  KVMState *s = cpu->kvm_state;
>> +CPUState *tmpcpu;
>>  
>>  QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
>>  if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
>>  /* Try harder to find a CPU that currently sees the breakpoint. 
>> */
>> -CPU_FOREACH(cpu) {
>> -if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
>> +CPU_FOREACH(tmpcpu) {
>> +if (kvm_arch_remove_sw_breakpoint(tmpcpu, bp) == 0) {
>>  break;
>>  }
>>  }
>>
> 
> Good catch. To make it clear in the changelog: The actual issue is that
> we misuse "cpu" as an iteration variable while its original value is
> still in use. That cpu can eventually become NULL this way is one result.
> 

OK, thanks. If necessary, I shall send patch v2 for additional comments.
(if really necessary to send, please let me know)


Thanks.
-- 
Chen Gang

Open share and attitude like air water and life which God blessed
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvm-all: Use 'tmpcpu' instead of 'cpu' in sub-looping to avoid 'cpu' be NULL

2014-07-20 Thread Jan Kiszka
On 2014-07-19 03:21, Chen Gang wrote:
> If kvm_arch_remove_sw_breakpoint() in CPU_FOREACH() always be fail, it
> will let 'cpu' NULL. And the next kvm_arch_remove_sw_breakpoint() in
> QTAILQ_FOREACH_SAFE() will get NULL parameter for 'cpu'.
> 
> And kvm_arch_remove_sw_breakpoint() can assumes 'cpu' must never be NULL,
> so need define additional temporary variable for 'cpu' to avoid the case.
> 
> 
> Signed-off-by: Chen Gang 
> ---
>  kvm-all.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/kvm-all.c b/kvm-all.c
> index 3ae30ee..1402f4f 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -2077,12 +2077,13 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
>  {
>  struct kvm_sw_breakpoint *bp, *next;
>  KVMState *s = cpu->kvm_state;
> +CPUState *tmpcpu;
>  
>  QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
>  if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
>  /* Try harder to find a CPU that currently sees the breakpoint. 
> */
> -CPU_FOREACH(cpu) {
> -if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
> +CPU_FOREACH(tmpcpu) {
> +if (kvm_arch_remove_sw_breakpoint(tmpcpu, bp) == 0) {
>  break;
>  }
>  }
> 

Good catch. To make it clear in the changelog: The actual issue is that
we misuse "cpu" as an iteration variable while its original value is
still in use. That cpu can eventually become NULL this way is one result.

Jan



signature.asc
Description: OpenPGP digital signature