From: Carsten Otte <[EMAIL PROTECTED]>
From: Christian Borntraeger <[EMAIL PROTECTED]>

This is an update patch for libkvm to build and work on s390.
It should address Avis and Christians comments.
Tested on s390. Compile tested on i386.
Avi please consider to apply.

Signed-off-by: Christian Borntraeger <[EMAIL PROTECTED]>

---
 Makefile                |    2 
 libkvm/config-s390.mak  |    3 +
 libkvm/config-s390x.mak |    3 +
 libkvm/kvm-common.h     |    7 ++
 libkvm/kvm-s390.h       |   31 +++++++++++
 libkvm/libkvm-s390.c    |  131 ++++++++++++++++++++++++++++++++++++++++++++++++
 libkvm/libkvm.c         |   23 ++++++++
 libkvm/libkvm.h         |   17 ++++++
 8 files changed, 215 insertions(+), 2 deletions(-)

Index: kvm-userspace/Makefile
===================================================================
--- kvm-userspace.orig/Makefile
+++ kvm-userspace/Makefile
@@ -5,7 +5,7 @@ DESTDIR=
 
 rpmrelease = devel
 
-sane-arch = $(subst i386,x86,$(subst x86_64,x86,$(ARCH)))
+sane-arch = $(subst i386,x86,$(subst x86_64,x86,$(subst s390x,s390,$(ARCH))))
 
 .PHONY: kernel user libkvm qemu bios vgabios extboot clean libfdt
 
Index: kvm-userspace/libkvm/config-s390.mak
===================================================================
--- /dev/null
+++ kvm-userspace/libkvm/config-s390.mak
@@ -0,0 +1,3 @@
+# s390 31bit mode
+LIBDIR := /lib
+libkvm-$(ARCH)-objs := libkvm-s390.o
Index: kvm-userspace/libkvm/config-s390x.mak
===================================================================
--- /dev/null
+++ kvm-userspace/libkvm/config-s390x.mak
@@ -0,0 +1,3 @@
+# s390 64 bit mode (arch=s390x)
+LIBDIR := /lib64
+libkvm-$(ARCH)-objs := libkvm-s390.o
Index: kvm-userspace/libkvm/kvm-common.h
===================================================================
--- kvm-userspace.orig/libkvm/kvm-common.h
+++ kvm-userspace/libkvm/kvm-common.h
@@ -18,8 +18,15 @@
 
 /* FIXME: share this number with kvm */
 /* FIXME: or dynamically alloc/realloc regions */
+#ifndef __s390__
 #define KVM_MAX_NUM_MEM_REGIONS 8u
 #define MAX_VCPUS 16
+#else
+#define KVM_MAX_NUM_MEM_REGIONS 1u
+#define MAX_VCPUS 64
+#define LIBKVM_S390_ORIGIN (0UL)
+#endif
+
 
 /* kvm abi verison variable */
 extern int kvm_abi;
Index: kvm-userspace/libkvm/kvm-s390.h
===================================================================
--- /dev/null
+++ kvm-userspace/libkvm/kvm-s390.h
@@ -0,0 +1,31 @@
+/*
+ * This header is for functions & variables that will ONLY be
+ * used inside libkvm for s390.
+ * THESE ARE NOT EXPOSED TO THE USER AND ARE ONLY FOR USE
+ * WITHIN LIBKVM.
+ *
+ * Copyright (C) 2006 Qumranet, Inc.
+ *
+ * Authors:
+ *     Avi Kivity   <[EMAIL PROTECTED]>
+ *     Yaniv Kamay  <[EMAIL PROTECTED]>
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors:
+ *     Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This work is licensed under the GNU LGPL license, version 2.
+ */
+
+#ifndef KVM_S390_H
+#define KVM_S390_H
+
+#include <asm/ptrace.h>
+#include "kvm-common.h"
+
+#define PAGE_SIZE 4096ul
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
+#define smp_wmb()   asm volatile("" ::: "memory")
+
+#endif
Index: kvm-userspace/libkvm/libkvm-s390.c
===================================================================
--- /dev/null
+++ kvm-userspace/libkvm/libkvm-s390.c
@@ -0,0 +1,131 @@
+/*
+ * This file contains the s390 specific implementation for the
+ * architecture dependent functions defined in kvm-common.h and
+ * libkvm.h
+ *
+ * Copyright (C) 2006 Qumranet
+ * Copyright IBM Corp. 2008
+ *
+ * Authors:
+ *     Carsten Otte <[EMAIL PROTECTED]>
+ *     Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This work is licensed under the GNU LGPL license, version 2.
+ */
+
+#include <sys/ioctl.h>
+#include <asm/ptrace.h>
+
+#include "libkvm.h"
+#include "kvm-common.h"
+#include <errno.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
+                               void **vm_mem)
+{
+       fprintf(stderr, "%s: Operation not supported\n", __FUNCTION__);
+       return -1;
+}
+
+void *kvm_create_kernel_phys_mem(kvm_context_t kvm, unsigned long phys_start,
+                                unsigned long len, int log, int writable)
+{
+       fprintf(stderr, "%s: Operation not supported\n", __FUNCTION__);
+       return NULL;
+}
+
+void kvm_show_code(kvm_context_t kvm, int vcpu)
+{
+       fprintf(stderr, "%s: Operation not supported\n", __FUNCTION__);
+}
+
+void kvm_show_regs(kvm_context_t kvm, int vcpu)
+{
+       struct kvm_regs regs;
+       struct kvm_sregs sregs;
+       int i;
+
+       if (kvm_get_regs(kvm, vcpu, &regs))
+               return;
+
+       if (kvm_get_sregs(kvm, vcpu, &sregs))
+               return;
+
+       fprintf(stderr, "guest vcpu #%d\n", vcpu);
+       fprintf(stderr, "PSW:\t%16.16lx %16.16lx\n",
+                                       kvm->run[vcpu]->s390_sieic.mask,
+                                       kvm->run[vcpu]->s390_sieic.addr);
+       fprintf(stderr,"GPRS:");
+       for (i=0; i<15; i+=4)
+               fprintf(stderr, "\t%16.16lx %16.16lx %16.16lx %16.16lx\n",
+                                                       regs.gprs[i],
+                                                       regs.gprs[i+1],
+                                                       regs.gprs[i+2],
+                                                       regs.gprs[i+3]);
+       fprintf(stderr,"ACRS:");
+       for (i=0; i<15; i+=4)
+               fprintf(stderr, "\t%8.8x %8.8x %8.8x %8.8x\n",
+                                                       sregs.acrs[i],
+                                                       sregs.acrs[i+1],
+                                                       sregs.acrs[i+2],
+                                                       sregs.acrs[i+3]);
+
+       fprintf(stderr,"CRS:");
+       for (i=0; i<15; i+=4)
+               fprintf(stderr, "\t%16.16lx %16.16lx %16.16lx %16.16lx\n",
+                                                       sregs.crs[i],
+                                                       sregs.crs[i+1],
+                                                       sregs.crs[i+2],
+                                                       sregs.crs[i+3]);
+}
+
+int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
+                        void **vm_mem)
+{
+       return 0;
+}
+
+int kvm_arch_create_default_phys_mem(kvm_context_t kvm,
+                                       unsigned long phys_mem_bytes,
+                                       void **vm_mem)
+{
+       return 0;
+}
+
+int kvm_arch_run(struct kvm_run *run, kvm_context_t kvm, int vcpu)
+{
+       int ret = 0;
+
+       switch (run->exit_reason){
+       default:
+               ret = 1;
+               break;
+       }
+       return ret;
+}
+
+int kvm_s390_initial_reset(kvm_context_t kvm, int slot)
+{
+       return ioctl(kvm->vcpu_fd[slot], KVM_S390_INITIAL_RESET, NULL);
+}
+
+int kvm_s390_interrupt(kvm_context_t kvm, int slot,
+       struct kvm_s390_interrupt *kvmint)
+{
+       if (slot>=0)
+               return ioctl(kvm->vcpu_fd[slot], KVM_S390_INTERRUPT, kvmint);
+       else
+               return ioctl(kvm->vm_fd, KVM_S390_INTERRUPT, kvmint);
+}
+
+int kvm_s390_set_initial_psw(kvm_context_t kvm, int slot, psw_t psw)
+{
+       return ioctl(kvm->vcpu_fd[slot], KVM_S390_SET_INITIAL_PSW, &psw);
+}
+
+int kvm_s390_store_status(kvm_context_t kvm, int slot, unsigned long addr)
+{
+       return ioctl(kvm->vcpu_fd[slot], KVM_S390_STORE_STATUS, addr);
+}
Index: kvm-userspace/libkvm/libkvm.c
===================================================================
--- kvm-userspace.orig/libkvm/libkvm.c
+++ kvm-userspace/libkvm/libkvm.c
@@ -48,6 +48,10 @@
 #include "kvm-powerpc.h"
 #endif
 
+#if defined(__s390__)
+#include "kvm-s390.h"
+#endif
+
 int kvm_abi = EXPECTED_KVM_API_VERSION;
 int kvm_page_size;
 
@@ -74,7 +78,7 @@ int get_free_slot(kvm_context_t kvm)
        int i;
        int tss_ext;
 
-#ifdef KVM_CAP_SET_TSS_ADDR
+#if defined(KVM_CAP_SET_TSS_ADDR) && !defined(__s390__)
        tss_ext = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
 #else
        tss_ext = 0;
@@ -410,7 +414,12 @@ void *kvm_create_userspace_phys_mem(kvm_
        if (writable)
                prot |= PROT_WRITE;
 
+#if !defined(__s390__)
        ptr = mmap(NULL, len, prot, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+#else
+       ptr = mmap(LIBKVM_S390_ORIGIN, len, prot | PROT_EXEC,
+               MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+#endif
        if (ptr == MAP_FAILED) {
                fprintf(stderr, "create_userspace_phys_mem: %s", 
strerror(errno));
                return 0;
@@ -895,8 +904,10 @@ int kvm_run(kvm_context_t kvm, int vcpu)
        struct kvm_run *run = kvm->run[vcpu];
 
 again:
+#if !defined(__s390__)
        if (!kvm->irqchip_in_kernel)
                run->request_interrupt_window = try_push_interrupts(kvm);
+#endif
        r = pre_kvm_run(kvm, vcpu);
        if (r)
            return r;
@@ -927,10 +938,12 @@ again:
        }
 #endif
 
+#if !defined(__s390__)
        if (r == -1) {
                r = handle_io_window(kvm);
                goto more;
        }
+#endif
        if (1) {
                switch (run->exit_reason) {
                case KVM_EXIT_UNKNOWN:
@@ -969,6 +982,14 @@ again:
                case KVM_EXIT_SHUTDOWN:
                        r = handle_shutdown(kvm, vcpu);
                        break;
+#if defined(__s390__)
+               case KVM_EXIT_S390_SIEIC:
+                       r = kvm->callbacks->s390_handle_intercept(kvm, vcpu,
+                               run);
+                       break;
+               case KVM_EXIT_S390_RESET:
+                       r = kvm->callbacks->s390_handle_reset(kvm, vcpu, run);
+#endif
                default:
                        if (kvm_arch_run(run, kvm, vcpu)) {
                                fprintf(stderr, "unhandled vm exit: 0x%x\n",
Index: kvm-userspace/libkvm/libkvm.h
===================================================================
--- kvm-userspace.orig/libkvm/libkvm.h
+++ kvm-userspace/libkvm/libkvm.h
@@ -5,6 +5,10 @@
 #ifndef LIBKVM_H
 #define LIBKVM_H
 
+#if defined(__s390__)
+#include <asm/ptrace.h>
+#endif
+
 #include <stdint.h>
 
 #ifndef __user
@@ -69,6 +73,12 @@ struct kvm_callbacks {
     int (*powerpc_dcr_read)(int vcpu, uint32_t dcrn, uint32_t *data);
     int (*powerpc_dcr_write)(int vcpu, uint32_t dcrn, uint32_t data);
 #endif
+#if defined(__s390__)
+    int (*s390_handle_intercept)(kvm_context_t context, int vcpu,
+       struct kvm_run *run);
+    int (*s390_handle_reset)(kvm_context_t context, int vcpu,
+        struct kvm_run *run);
+#endif
 };
 
 /*!
@@ -639,4 +649,11 @@ int kvm_enable_vapic(kvm_context_t kvm, 
 
 #endif
 
+#if defined(__s390__)
+int kvm_s390_initial_reset(kvm_context_t kvm, int slot);
+int kvm_s390_interrupt(kvm_context_t kvm, int slot,
+       struct kvm_s390_interrupt *kvmint);
+int kvm_s390_set_initial_psw(kvm_context_t kvm, int slot, psw_t psw);
+int kvm_s390_store_status(kvm_context_t kvm, int slot, unsigned long addr);
+#endif
 #endif
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to