All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/13] S390x KVM support v4
@ 2009-11-24 17:29 Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 01/13] S/390 CPU fake emulation Alexander Graf
                   ` (12 more replies)
  0 siblings, 13 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

While S390x was one of the first targets that were supported by KVM it always
lacked qemu system emulation support.

In order to change that sad fact, I figured I'd just take on the task myself,
taking kuli (http://www.ibm.com/developerworks/linux/linux390/kuli.html),
Documentation/s390/kvm.txt and lguest as starting points to write a clean,
qemu'ish S390x Virtio machine emulation.

So now you can run Linux VMs on Linux on z/VM on LPAR on zSeries!

This is the resulting code. Please comment on things you like and also on the
ones you don't :-).

The patchset is based on Uli's S390x userspace emulation patches. There's not
really that much shared functionality, but I didn't want to reimplement the
configure wheels. So make sure to have his patches applied first.

Please only run S390x system virtualization using io threads. S390x has very
few intercepts and even less that actually reach userspace. So you'll end up
with a non-responsive VM without a dedicated IO thread.

Use: $ ./configure --target-list=s390x-softmmu --enable-io-thread

Currently only -kernel, -initrd and friends work. Booting from a real dasd
device is not supported.

Also to actually run this code you need a patch for an ugly bug in the kernel
module that Carsten sent a patch to on the ML.

I verified that the userspace actually works on a 2.6.27 (SLES11) kernel, so
if it doesn't work on current git, please tell me! I'm too afraid that I might
end up in a 3270 terminal to update the kernel on my z/VM instance :-).

##### WARNING #####

Apparently the qemu review process has scared off yet another developer for now.

So I'm sending this patchset without relying on Uli's set but rather
implemented small stubs for TCG host and TCG guest support, so we can run
on KVM. He promised me to send it again "soon" - whenever that is.

These stubs don't serve any purpose but to get KVM running, so you get no x86
on S390X or S390X on x86 for now!

##################

v1 -> v2:

  - use new kvm_run variables
  - use DO_UPCAST
  - add bridge device for "info qtree"

v2 -> v3:

  - move memory allocation logic to qemu_ram_alloc

v3 -> v4:

  - minor bugfixes
  - adjust to more recent qdev nic code
  - zipl loader
  - include fake emulation series

Alexander Graf (13):
  S/390 CPU fake emulation
  S/390 host/target build system support
  S/390 fake TCG implementation
  Add KVM support for S390x
  Allocate physical memory in low virtual address space
  Add support for S390x system emulation
  Add S390x virtio machine bus
  Add S390x virtio machine description
  S390 GDB stub
  Implement early printk in virtio-console
  Set default console to virtio on S390x
  Add zipl bootloader interpreter
  Add S390 maintainer information

 MAINTAINERS                       |    3 +
 Makefile.target                   |    2 +
 configure                         |   24 ++-
 cpu-exec.c                        |    2 +
 dyngen-exec.h                     |    2 +-
 exec.c                            |    6 +
 gdbstub.c                         |   52 ++++
 hw/s390-virtio-bus.c              |  385 ++++++++++++++++++++++++++++++
 hw/s390-virtio-bus.h              |   65 +++++
 hw/s390-virtio.c                  |  248 ++++++++++++++++++++
 hw/s390-zipl.c                    |  233 +++++++++++++++++++
 hw/virtio-console.c               |    7 +
 hw/virtio-console.h               |    2 +
 target-s390x/cpu.h                |  269 +++++++++++++++++++++
 target-s390x/exec.h               |   56 +++++
 target-s390x/helper.c             |   84 +++++++
 target-s390x/kvm.c                |  463 +++++++++++++++++++++++++++++++++++++
 target-s390x/machine.c            |   30 +++
 target-s390x/op_helper.c          |   74 ++++++
 target-s390x/translate.c          |   57 +++++
 tcg/s390/tcg-target.c             |  103 ++++++++
 tcg/s390/tcg-target.h             |   48 ++++
 vl.c                              |   26 ++
 23 files changed, 2233 insertions(+), 8 deletions(-)
 create mode 100644 default-configs/s390x-softmmu.mak
 create mode 100644 hw/s390-virtio-bus.c
 create mode 100644 hw/s390-virtio-bus.h
 create mode 100644 hw/s390-virtio.c
 create mode 100644 hw/s390-zipl.c
 create mode 100644 target-s390x/cpu.h
 create mode 100644 target-s390x/exec.h
 create mode 100644 target-s390x/helper.c
 create mode 100644 target-s390x/kvm.c
 create mode 100644 target-s390x/machine.c
 create mode 100644 target-s390x/op_helper.c
 create mode 100644 target-s390x/translate.c
 create mode 100644 tcg/s390/tcg-target.c
 create mode 100644 tcg/s390/tcg-target.h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 01/13] S/390 CPU fake emulation
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 02/13] S/390 host/target build system support Alexander Graf
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

Because Qemu currently requires a TCG target to exist and there are quite some
useful helpers here to lay the groundwork for out KVM target, let's create a
stub TCG emulation target for S390X CPUs.

This is required to make tcg happy. The emulation target itself won't work
though.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 cpu-exec.c               |    2 +
 target-s390x/cpu.h       |  119 ++++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/exec.h      |   51 ++++++++++++++++++++
 target-s390x/helper.c    |   57 ++++++++++++++++++++++
 target-s390x/op_helper.c |   74 ++++++++++++++++++++++++++++
 target-s390x/translate.c |   57 ++++++++++++++++++++++
 6 files changed, 360 insertions(+), 0 deletions(-)
 create mode 100644 target-s390x/cpu.h
 create mode 100644 target-s390x/exec.h
 create mode 100644 target-s390x/helper.c
 create mode 100644 target-s390x/op_helper.c
 create mode 100644 target-s390x/translate.c

diff --git a/cpu-exec.c b/cpu-exec.c
index 2c0765c..af4595b 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -249,6 +249,7 @@ int cpu_exec(CPUState *env1)
 #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_CRIS)
+#elif defined(TARGET_S390X)
     /* XXXXX */
 #else
 #error unsupported target CPU
@@ -673,6 +674,7 @@ int cpu_exec(CPUState *env1)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_CRIS)
+#elif defined(TARGET_S390X)
     /* XXXXX */
 #else
 #error unsupported target CPU
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
new file mode 100644
index 0000000..f45b00c
--- /dev/null
+++ b/target-s390x/cpu.h
@@ -0,0 +1,119 @@
+/*
+ * S/390 virtual CPU header
+ *
+ *  Copyright (c) 2009 Ulrich Hecht
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+#ifndef CPU_S390X_H
+#define CPU_S390X_H
+
+#define TARGET_LONG_BITS 64
+
+#define ELF_MACHINE	EM_S390
+
+#define CPUState struct CPUS390XState
+
+#include "cpu-defs.h"
+
+#include "softfloat.h"
+
+#define NB_MMU_MODES 2 // guess
+#define MMU_USER_IDX 0 // guess
+
+typedef union FPReg {
+    struct {
+#ifdef WORDS_BIGENDIAN
+        float32 e;
+        int32_t __pad;
+#else
+        int32_t __pad;
+        float32 e;
+#endif
+    };
+    float64 d;
+    uint64_t i;
+} FPReg;
+
+typedef struct CPUS390XState {
+    uint64_t regs[16];	/* GP registers */
+    
+    uint32_t aregs[16];	/* access registers */
+    
+    uint32_t fpc;	/* floating-point control register */
+    FPReg fregs[16]; /* FP registers */
+    float_status fpu_status; /* passed to softfloat lib */
+    
+    struct {
+        uint64_t mask;
+        uint64_t addr;
+    } psw;
+    
+    int cc; /* condition code (0-3) */
+    
+    uint64_t __excp_addr;
+    
+    CPU_COMMON
+} CPUS390XState;
+
+#if defined(CONFIG_USER_ONLY)
+static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+{
+    if (newsp)
+        env->regs[15] = newsp;
+    env->regs[0] = 0;
+}
+#endif
+
+CPUS390XState *cpu_s390x_init(const char *cpu_model);
+int cpu_s390x_exec(CPUS390XState *s);
+void cpu_s390x_close(CPUS390XState *s);
+
+/* you can call this signal handler from your SIGBUS and SIGSEGV
+   signal handlers to inform the virtual CPU of exceptions. non zero
+   is returned if the signal was handled by the virtual CPU.  */
+int cpu_s390x_signal_handler(int host_signum, void *pinfo,
+                           void *puc);
+int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
+                              int mmu_idx, int is_softmuu);
+#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
+
+#define TARGET_PAGE_BITS 12
+
+#define cpu_init cpu_s390x_init
+#define cpu_exec cpu_s390x_exec
+#define cpu_gen_code cpu_s390x_gen_code
+
+#include "cpu-all.h"
+#include "exec-all.h"
+
+#define EXCP_OPEX 1 /* operation exception (sigill) */
+#define EXCP_SVC 2 /* supervisor call (syscall) */
+#define EXCP_ADDR 5 /* addressing exception */
+#define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
+{
+    env->psw.addr = tb->pc;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
+                                        target_ulong *cs_base, int *flags)
+{
+    *pc = env->psw.addr;
+    *cs_base = 0;
+    *flags = env->psw.mask; // guess
+}
+#endif
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
new file mode 100644
index 0000000..5198359
--- /dev/null
+++ b/target-s390x/exec.h
@@ -0,0 +1,51 @@
+/*
+ *  S/390 execution defines
+ *
+ *  Copyright (c) 2009 Ulrich Hecht
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "dyngen-exec.h"
+
+register struct CPUS390XState *env asm(AREG0);
+
+#include "cpu.h"
+#include "exec-all.h"
+
+static inline int cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+static inline void env_to_regs(void)
+{
+}
+
+static inline int cpu_halted(CPUState *env)
+{
+    if (!env->halted) {
+       return 0;
+    }
+    if (cpu_has_work(env)) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
new file mode 100644
index 0000000..4e23b4a
--- /dev/null
+++ b/target-s390x/helper.c
@@ -0,0 +1,57 @@
+/*
+ *  S/390 helpers
+ *
+ *  Copyright (c) 2009 Ulrich Hecht
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "gdbstub.h"
+#include "qemu-common.h"
+
+CPUS390XState *cpu_s390x_init(const char *cpu_model)
+{
+    CPUS390XState *env;
+    static int inited = 0;
+    
+    env = qemu_mallocz(sizeof(CPUS390XState));
+    cpu_exec_init(env);
+    if (!inited) {
+        inited = 1;
+    }
+    
+    env->cpu_model_str = cpu_model;
+    cpu_reset(env);
+    qemu_init_vcpu(env);
+    return env;
+}
+
+void cpu_reset(CPUS390XState *env)
+{
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+    
+    memset(env, 0, offsetof(CPUS390XState, breakpoints));
+    /* FIXME: reset vector? */
+    tlb_flush(env, 1);
+}
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
new file mode 100644
index 0000000..e623de9
--- /dev/null
+++ b/target-s390x/op_helper.c
@@ -0,0 +1,74 @@
+/*
+ *  S/390 helper routines
+ *
+ *  Copyright (c) 2009 Alexander Graf
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "exec.h"
+
+/*****************************************************************************/
+/* Softmmu support */
+#if !defined (CONFIG_USER_ONLY)
+
+#define MMUSUFFIX _mmu
+
+#define SHIFT 0
+#include "softmmu_template.h"
+
+#define SHIFT 1
+#include "softmmu_template.h"
+
+#define SHIFT 2
+#include "softmmu_template.h"
+
+#define SHIFT 3
+#include "softmmu_template.h"
+
+/* try to fill the TLB and return an exception if error. If retaddr is
+   NULL, it means that the function was called in C code (i.e. not
+   from generated code or from helper.c) */
+/* XXX: fix it to restore all registers */
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
+{
+    TranslationBlock *tb;
+    CPUState *saved_env;
+    unsigned long pc;
+    int ret;
+
+    /* XXX: hack to restore env in all cases, even if not called from
+       generated code */
+    saved_env = env;
+    env = cpu_single_env;
+    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    if (unlikely(ret != 0)) {
+        if (likely(retaddr)) {
+            /* now we have a real cpu fault */
+            pc = (unsigned long)retaddr;
+            tb = tb_find_pc(pc);
+            if (likely(tb)) {
+                /* the PC is inside the translated code. It means that we have
+                   a virtual CPU fault */
+                cpu_restore_state(tb, env, pc, NULL);
+            }
+        }
+        /* XXX */
+        /* helper_raise_exception_err(env->exception_index, env->error_code); */
+    }
+    env = saved_env;
+}
+
+#endif
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
new file mode 100644
index 0000000..f304411
--- /dev/null
+++ b/target-s390x/translate.c
@@ -0,0 +1,57 @@
+/*
+ *  S/390 translation
+ *
+ *  Copyright (c) 2009 Ulrich Hecht
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "disas.h"
+#include "tcg-op.h"
+#include "qemu-log.h"
+
+void cpu_dump_state(CPUState *env, FILE *f,
+                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+                    int flags)
+{
+    int i;
+    for (i = 0; i < 16; i++) {
+        cpu_fprintf(f, "R%02d=%016lx", i, env->regs[i]);
+        if ((i % 4) == 3) cpu_fprintf(f, "\n");
+        else cpu_fprintf(f, " ");
+    }
+    for (i = 0; i < 16; i++) {
+        cpu_fprintf(f, "F%02d=%016lx", i, env->fregs[i]);
+        if ((i % 4) == 3) cpu_fprintf(f, "\n");
+        else cpu_fprintf(f, " ");
+    }
+    cpu_fprintf(f, "PSW=mask %016lx addr %016lx cc %02x\n", env->psw.mask, env->psw.addr, env->cc);
+}
+
+void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
+{
+}
+
+void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
+{
+}
+
+void gen_pc_load(CPUState *env, TranslationBlock *tb,
+                unsigned long searched_pc, int pc_pos, void *puc)
+{
+    env->psw.addr = gen_opc_pc[pc_pos];
+}
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 02/13] S/390 host/target build system support
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 01/13] S/390 CPU fake emulation Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 03/13] S/390 fake TCG implementation Alexander Graf
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

This patch makes configure aware of S390 hosts and guests. When not explicitly
defined using --target-list= no S390 targets will be built though.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 configure |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index e108dfb..72a6f91 100755
--- a/configure
+++ b/configure
@@ -158,9 +158,12 @@ case "$cpu" in
   parisc|parisc64)
     cpu="hppa"
   ;;
-  s390*)
+  s390)
     cpu="s390"
   ;;
+  s390x)
+    cpu="s390x"
+  ;;
   sparc|sun4[cdmuv])
     cpu="sparc"
   ;;
@@ -860,7 +863,7 @@ fi
 # host long bits test
 hostlongbits="32"
 case "$cpu" in
-  x86_64|alpha|ia64|sparc64|ppc64)
+  x86_64|alpha|ia64|sparc64|ppc64|s390x)
     hostlongbits=64
   ;;
 esac
@@ -1872,7 +1875,7 @@ echo >> $config_host_mak
 echo "CONFIG_QEMU_SHAREDIR=\"$prefix$datasuffix\"" >> $config_host_mak
 
 case "$cpu" in
-  i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64)
+  i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64)
     ARCH=$cpu
   ;;
   armv4b|armv4l)
@@ -2158,7 +2161,7 @@ target_arch2=`echo $target | cut -d '-' -f 1`
 target_bigendian="no"
 
 case "$target_arch2" in
-  armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|sh4eb|sparc|sparc64|sparc32plus)
+  armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus)
   target_bigendian=yes
   ;;
 esac
@@ -2330,6 +2333,9 @@ case "$target_arch2" in
     echo "TARGET_ABI32=y" >> $config_target_mak
     target_phys_bits=64
   ;;
+  s390x)
+    target_phys_bits=64
+  ;;
   *)
     echo "Unsupported target CPU"
     exit 1
@@ -2398,7 +2404,7 @@ if test ! -z "$gdb_xml_files" ; then
 fi
 
 case "$target_arch2" in
-  arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|sparc|sparc64|sparc32plus)
+  arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|s390x|sparc|sparc64|sparc32plus)
     echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
     ;;
   *)
@@ -2431,6 +2437,8 @@ ldflags=""
 
 if test "$ARCH" = "sparc64" ; then
   cflags="-I\$(SRC_PATH)/tcg/sparc $cflags"
+elif test "$ARCH" = "s390x" ; then
+  cflags="-I\$(SRC_PATH)/tcg/s390 $cflags"
 else
   cflags="-I\$(SRC_PATH)/tcg/\$(ARCH) $cflags"
 fi
@@ -2466,7 +2474,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   ppc*)
     echo "CONFIG_PPC_DIS=y"  >> $config_target_mak
   ;;
-  s390)
+  s390*)
     echo "CONFIG_S390_DIS=y"  >> $config_target_mak
   ;;
   sh4)
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 03/13] S/390 fake TCG implementation
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 01/13] S/390 CPU fake emulation Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 02/13] S/390 host/target build system support Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 04/13] Add KVM support for S390x Alexander Graf
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

Qemu won't let us run a KVM target without having host TCG support. Well, for
now we don't have any so let's implement a fake target that only stubs out
everything.

I tried to keep the patch as close to Uli's source as possible, so whenever
he feels like it he can easily diff his version against this one.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 dyngen-exec.h         |    2 +-
 target-s390x/helper.c |    5 ++
 tcg/s390/tcg-target.c |  103 +++++++++++++++++++++++++++++++++++++++++++++++++
 tcg/s390/tcg-target.h |   48 +++++++++++++++++++++++
 4 files changed, 157 insertions(+), 1 deletions(-)
 create mode 100644 tcg/s390/tcg-target.c
 create mode 100644 tcg/s390/tcg-target.h

diff --git a/dyngen-exec.h b/dyngen-exec.h
index 86e61c3..0353f36 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -117,7 +117,7 @@ extern int printf(const char *, ...);
 
 /* The return address may point to the start of the next instruction.
    Subtracting one gets us the call instruction itself.  */
-#if defined(__s390__)
+#if defined(__s390__) && !defined(__s390x__)
 # define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1))
 #elif defined(__arm__)
 /* Thumb return addresses have the low bit set, so we need to subtract two.
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 4e23b4a..0e222e3 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -44,6 +44,11 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model)
     return env;
 }
 
+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+    return addr;
+}
+
 void cpu_reset(CPUS390XState *env)
 {
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
new file mode 100644
index 0000000..53bbf69
--- /dev/null
+++ b/tcg/s390/tcg-target.c
@@ -0,0 +1,103 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+static const int tcg_target_reg_alloc_order[] = {
+};
+
+static const int tcg_target_call_iarg_regs[] = {
+};
+
+static const int tcg_target_call_oarg_regs[] = {
+};
+
+static void patch_reloc(uint8_t *code_ptr, int type,
+                tcg_target_long value, tcg_target_long addend)
+{
+    tcg_abort();
+}
+
+static inline int tcg_target_get_call_iarg_regs_count(int flags)
+{
+    tcg_abort();
+    return 0;
+}
+
+/* parse target specific constraints */
+static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+{
+    tcg_abort();
+    return 0;
+}
+
+/* Test if a constant matches the constraint. */
+static inline int tcg_target_const_match(tcg_target_long val,
+                const TCGArgConstraint *arg_ct)
+{
+    tcg_abort();
+    return 0;
+}
+
+/* load a register with an immediate value */
+static inline void tcg_out_movi(TCGContext *s, TCGType type,
+                int ret, tcg_target_long arg)
+{
+    tcg_abort();
+}
+
+/* load data without address translation or endianness conversion */
+static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
+                int arg1, tcg_target_long arg2)
+{
+    tcg_abort();
+}
+
+static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
+                              int arg1, tcg_target_long arg2)
+{
+    tcg_abort();
+}
+
+static inline void tcg_out_op(TCGContext *s, int opc,
+                const TCGArg *args, const int *const_args)
+{
+    tcg_abort();
+}
+
+void tcg_target_init(TCGContext *s)
+{
+}
+
+void tcg_target_qemu_prologue(TCGContext *s)
+{
+}
+
+static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
+{
+    tcg_abort();
+}
+
+static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+{
+    tcg_abort();
+}
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
new file mode 100644
index 0000000..2e66553
--- /dev/null
+++ b/tcg/s390/tcg-target.h
@@ -0,0 +1,48 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#define TCG_TARGET_S390 1
+
+#define TCG_TARGET_REG_BITS 64
+#define TCG_TARGET_WORDS_BIGENDIAN
+
+#define TCG_TARGET_NB_REGS 0
+
+enum {
+    TCG_AREG0 = 0,
+};
+
+/* used for function call generation */
+#define TCG_REG_CALL_STACK		0
+#define TCG_TARGET_STACK_ALIGN		8
+#define TCG_TARGET_CALL_STACK_OFFSET	0
+
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+#if QEMU_GNUC_PREREQ(4, 1)
+    void __clear_cache(char *beg, char *end);
+    __clear_cache((char *) start, (char *) stop);
+#else
+#error not implemented
+#endif
+}
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 04/13] Add KVM support for S390x
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (2 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 03/13] S/390 fake TCG implementation Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 05/13] Allocate physical memory in low virtual address space Alexander Graf
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

S390x was one of the first platforms that received support for KVM back in the
day. Unfortunately until now there hasn't been a qemu implementation that would
enable users to actually run guests.

So let's include support for KVM S390x in qemu!

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 configure          |    4 +-
 target-s390x/kvm.c |  463 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 466 insertions(+), 1 deletions(-)
 create mode 100644 target-s390x/kvm.c

diff --git a/configure b/configure
index 72a6f91..0e1db51 100755
--- a/configure
+++ b/configure
@@ -1346,6 +1346,8 @@ EOF
             kvm_cflags="$kvm_cflags -I$kerneldir/arch/x86/include"
 	elif test "$cpu" = "ppc" -a -d "$kerneldir/arch/powerpc/include" ; then
 	    kvm_cflags="$kvm_cflags -I$kerneldir/arch/powerpc/include"
+	elif test "$cpu" = "s390x" -a -d "$kerneldir/arch/s390/include" ; then
+	    kvm_cflags="$kvm_cflags -I$kerneldir/arch/s390/include"
         elif test -d "$kerneldir/arch/$cpu/include" ; then
             kvm_cflags="$kvm_cflags -I$kerneldir/arch/$cpu/include"
       fi
@@ -2364,7 +2366,7 @@ case "$target_arch2" in
     fi
 esac
 case "$target_arch2" in
-  i386|x86_64|ppcemb|ppc|ppc64)
+  i386|x86_64|ppcemb|ppc|ppc64|s390x)
     # Make sure the target and host cpus are compatible
     if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
       \( "$target_arch2" = "$cpu" -o \
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
new file mode 100644
index 0000000..d477664
--- /dev/null
+++ b/target-s390x/kvm.c
@@ -0,0 +1,463 @@
+/*
+ * QEMU S390x KVM implementation
+ *
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/kvm.h>
+#include <asm/ptrace.h>
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "kvm.h"
+#include "cpu.h"
+#include "device_tree.h"
+
+/* #define DEBUG_KVM */
+
+#ifdef DEBUG_KVM
+#define dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+#define IPA0_DIAG               0x8300
+#define IPA0_SIGP               0xae00
+#define IPA0_PRIV               0xb200
+
+#define PRIV_SCLP_CALL          0x20
+#define DIAG_KVM_HYPERCALL      0x500
+#define DIAG_KVM_BREAKPOINT     0x501
+
+#define SCP_LENGTH              0x00
+#define SCP_FUNCTION_CODE       0x02
+#define SCP_CONTROL_MASK        0x03
+#define SCP_RESPONSE_CODE       0x06
+#define SCP_MEM_CODE            0x08
+#define SCP_INCREMENT           0x0a
+
+#define ICPT_INSTRUCTION        0x04
+#define ICPT_WAITPSW            0x1c
+#define ICPT_SOFT_INTERCEPT     0x24
+#define ICPT_CPU_STOP           0x28
+#define ICPT_IO                 0x40
+
+#define SIGP_RESTART            0x06
+#define SIGP_INITIAL_CPU_RESET  0x0b
+#define SIGP_STORE_STATUS_ADDR  0x0e
+#define SIGP_SET_ARCH           0x12
+
+
+int kvm_arch_init(KVMState *s, int smp_cpus)
+{
+    return 0;
+}
+
+int kvm_arch_init_vcpu(CPUState *env)
+{
+    int ret = 0;
+
+    if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0)
+        perror("cannot init reset vcpu");
+
+    return ret;
+}
+
+void kvm_arch_reset_vcpu(CPUState *env)
+{
+}
+
+int kvm_arch_put_registers(CPUState *env)
+{
+    struct kvm_regs regs;
+    int ret;
+    int i;
+
+    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
+    if (ret < 0)
+        return ret;
+
+    for (i = 0; i < 16; i++)
+        regs.gprs[i] = env->regs[i];
+
+    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
+    if (ret < 0)
+        return ret;
+
+    env->kvm_run->psw_addr = env->psw.addr;
+    env->kvm_run->psw_mask = env->psw.mask;
+
+    return ret;
+}
+
+int kvm_arch_get_registers(CPUState *env)
+{
+    uint32_t ret;
+    struct kvm_regs regs;
+    int i;
+
+    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
+    if (ret < 0)
+        return ret;
+
+    for (i = 0; i < 16; i++)
+        env->regs[i] = regs.gprs[i];
+
+    env->psw.addr = env->kvm_run->psw_addr;
+    env->psw.mask = env->kvm_run->psw_mask;
+
+    return 0;
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
+{
+    static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
+
+    if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
+        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)diag_501, 4, 1))
+        return -EINVAL;
+    return 0;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
+{
+    uint8_t t[4];
+    static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
+
+    if (cpu_memory_rw_debug(env, bp->pc, t, 4, 0))
+        return -EINVAL;
+    if (memcmp(t, diag_501, 4))
+        return -EINVAL;
+    if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1))
+        return -EINVAL;
+
+    return 0;
+}
+
+int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
+{
+    return 0;
+}
+
+int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
+{
+    return 0;
+}
+
+static void _kvm_s390_interrupt(CPUState *env, int type, uint32_t parm, uint64_t parm64, int vm)
+{
+    struct kvm_s390_interrupt kvmint;
+    int r;
+
+    if (!env->kvm_state)
+        return;
+
+    env->halted = 0;
+    env->exception_index = 0;
+
+    kvmint.type = type;
+    kvmint.parm = parm;
+    kvmint.parm64 = parm64;
+
+    if (vm)
+        r = kvm_vm_ioctl(env->kvm_state, KVM_S390_INTERRUPT, &kvmint);
+    else 
+        r = kvm_vcpu_ioctl(env, KVM_S390_INTERRUPT, &kvmint);
+
+    if (r < 0) {
+        fprintf(stderr, "KVM failed to inject interrupt\n");
+        exit(1);
+    }
+}
+
+void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token)
+{
+    _kvm_s390_interrupt(env, KVM_S390_INT_VIRTIO, config_change, token, 1);
+}
+
+static void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
+{
+    _kvm_s390_interrupt(env, type, code, 0, 0);
+}
+
+static void enter_pgmcheck(CPUState *env, uint16_t code)
+{
+    kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
+}
+
+static void setcc(CPUState *env, uint64_t cc)
+{
+    env->kvm_run->psw_mask &= ~(3ul << 44);
+    env->kvm_run->psw_mask |= (cc & 3) << 44;
+
+    env->psw.mask &= ~(3ul << 44);
+    env->psw.mask |= (cc & 3) << 44;
+}
+
+static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0)
+{
+    uint32_t sccb;
+    uint64_t code;
+    int r = 0;
+
+    cpu_synchronize_state(env);
+    sccb = env->regs[ipbh0 & 0xf];
+    code = env->regs[(ipbh0 & 0xf0) >> 4];
+
+    dprintf("sclp(0x%x, 0x%lx)\n", sccb, code);
+
+    if (sccb & ~0x7ffffff8ul) {
+        fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb);
+        r = -1;
+        goto out;
+    }
+
+    switch(code) {
+        case 0x00020001:
+        case 0x00120001:
+            stw_phys(sccb + SCP_MEM_CODE, ram_size >> 20);
+            stb_phys(sccb + SCP_INCREMENT, 1);
+            stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
+            setcc(env, 0);
+
+            _kvm_s390_interrupt(env, KVM_S390_INT_SERVICE, sccb & ~3, 0, 1);
+            break;
+        default:
+            dprintf("KVM: invalid sclp call 0x%x / 0x%lx\n", sccb, code);
+            r = -1;
+            break;
+    }
+
+out:
+    if (r < 0)
+        setcc(env, 3);
+    return 0;
+}
+
+static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
+{
+    int r = 0;
+    uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;
+
+    dprintf("KVM: PRIV: %d\n", ipa1);
+    switch (ipa1) {
+        case PRIV_SCLP_CALL:
+            r = sclp_service_call(env, run, ipbh0);
+            break;
+        default:
+            dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
+            r = -1;
+            break;
+    }
+
+    return r;
+}
+
+static int handle_hypercall(CPUState *env, struct kvm_run *run)
+{
+    int r;
+
+    cpu_synchronize_state(env);
+    r = s390_virtio_hypercall(env);
+    kvm_arch_put_registers(env);
+
+    return r;
+}
+
+static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code)
+{
+    int r = 0;
+
+    switch (ipb_code) {
+        case DIAG_KVM_HYPERCALL:
+            r = handle_hypercall(env, run);
+            break;
+        case DIAG_KVM_BREAKPOINT:
+            sleep(10);
+            break;
+        default:
+            dprintf("KVM: unknown DIAG: 0x%x\n", ipb_code);
+            r = -1;
+            break;
+    }
+
+    return r;
+}
+
+static int s390_cpu_restart(CPUState *env)
+{
+    kvm_s390_interrupt(env, KVM_S390_RESTART, 0);
+    env->halted = 0;
+    env->exception_index = 0;
+    qemu_cpu_kick(env);
+    fprintf(stderr, "DONE: SIGP cpu restart: %p\n", env);
+    return 0;
+}
+
+static int s390_store_status(CPUState *env, uint32_t parameter)
+{
+    /* XXX */
+    fprintf(stderr, "XXX SIGP store status\n");
+    return -1;
+}
+
+static int s390_cpu_initial_reset(CPUState *env)
+{
+    /* XXX */
+    fprintf(stderr, "XXX SIGP init\n");
+    return -1;
+}
+
+static int handle_sigp(CPUState *env, struct kvm_run *run, uint8_t ipa1)
+{
+    uint8_t order_code;
+    uint32_t parameter;
+    uint16_t cpu_addr;
+    uint8_t t;
+    int r = -1;
+    CPUState *target_env;
+
+    cpu_synchronize_state(env);
+
+    /* get order code */
+    order_code = run->s390_sieic.ipb >> 28;
+    if (order_code > 0)
+        order_code = env->regs[order_code];
+    order_code += (run->s390_sieic.ipb & 0x0fff0000) >> 16;
+
+    /* get parameters */
+    t = (ipa1 & 0xf0) >> 4;
+    if (!(t % 2))
+        t++;
+
+    parameter = env->regs[t] & 0x7ffffe00;
+    cpu_addr = env->regs[ipa1 & 0x0f];
+
+    target_env = s390_cpu_addr2state(cpu_addr);
+    if (!target_env)
+        goto out;
+
+    switch (order_code) {
+        case SIGP_RESTART:
+            r = s390_cpu_restart(target_env);
+            break;
+        case SIGP_STORE_STATUS_ADDR:
+            r = s390_store_status(target_env, parameter);
+            break;
+        case SIGP_SET_ARCH:
+            /* make the caller panic */
+            return -1;
+        case SIGP_INITIAL_CPU_RESET:
+            r = s390_cpu_initial_reset(target_env);
+            break;
+        default:
+            fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", ipa1);
+            break;
+    }
+
+out:
+    setcc(env, r ? 3 : 0);
+    return 0;
+}
+
+static int handle_instruction(CPUState *env, struct kvm_run *run)
+{
+    unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
+    uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
+    int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
+    int r = 0;
+
+    dprintf("handle_instruction 0x%x 0x%x\n", run->s390_sieic.ipa, run->s390_sieic.ipb);
+    switch (ipa0) {
+        case IPA0_PRIV:
+            r = handle_priv(env, run, ipa1);
+            break;
+        case IPA0_DIAG:
+            r = handle_diag(env, run, ipb_code);
+            break;
+        case IPA0_SIGP:
+            r = handle_sigp(env, run, ipa1);
+            break;
+    }
+
+    if (r < 0) {
+        enter_pgmcheck(env, 0x0001);
+    }
+    return r;
+}
+
+static int handle_intercept(CPUState *env)
+{
+    struct kvm_run *run = env->kvm_run;
+    int icpt_code = run->s390_sieic.icptcode;
+    int r = 0;
+
+    dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code, env->kvm_run->psw_addr);
+    switch (icpt_code) {
+        case ICPT_INSTRUCTION:
+            r = handle_instruction(env, run);
+            break;
+        case ICPT_WAITPSW:
+            /* XXX What to do on system shutdown? */
+            env->halted = 1;
+            env->exception_index = EXCP_HLT;
+            break;
+        case ICPT_SOFT_INTERCEPT:
+            fprintf(stderr, "KVM unimplemented icpt SOFT\n");
+            exit(1);
+            break;
+        case ICPT_CPU_STOP:
+            qemu_system_shutdown_request();
+            break;
+        case ICPT_IO:
+            fprintf(stderr, "KVM unimplemented icpt IO\n");
+            exit(1);
+            break;
+        default:
+            fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);
+            exit(1);
+            break;
+    }
+
+    return r;
+}
+
+int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
+{
+    int ret = 0;
+
+    switch (run->exit_reason) {
+        case KVM_EXIT_S390_SIEIC:
+            ret = handle_intercept(env);
+            break;
+        case KVM_EXIT_S390_RESET:
+            fprintf(stderr, "RESET not implemented\n");
+            exit(1);
+            break;
+        default:
+            fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
+            break;
+    }
+
+    return ret;
+}
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 05/13] Allocate physical memory in low virtual address space
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (3 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 04/13] Add KVM support for S390x Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation Alexander Graf
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

KVM on S390x requires the virtual address space of the guest's RAM to be
within the first 256GB.

The general direction I'd like to see KVM on S390 move is that this requirement
is losened, but for now that's what we're stuck with.

So let's just hack up qemu_ram_alloc until KVM behaves nicely :-).

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 exec.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/exec.c b/exec.c
index 076d26b..59150d0 100644
--- a/exec.c
+++ b/exec.c
@@ -2411,7 +2411,13 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size)
     size = TARGET_PAGE_ALIGN(size);
     new_block = qemu_malloc(sizeof(*new_block));
 
+#if defined(TARGET_S390) && defined(CONFIG_KVM)
+    /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */
+    new_block->host = mmap(0x1000000, size, PROT_EXEC|PROT_READ|PROT_WRITE,
+                           MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+#else
     new_block->host = qemu_vmalloc(size);
+#endif
 #ifdef MADV_MERGEABLE
     madvise(new_block->host, size, MADV_MERGEABLE);
 #endif
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (4 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 05/13] Allocate physical memory in low virtual address space Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-25 11:46   ` Paul Brook
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 07/13] Add S390x virtio machine bus Alexander Graf
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

Let's enable the basics for system emulation so we can run virtual machines
with KVM!

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-s390x/cpu.h                |  153 ++++++++++++++++++++++++++++++++++++-
 target-s390x/exec.h               |    5 +
 target-s390x/helper.c             |   22 +++++
 target-s390x/machine.c            |   30 +++++++
 4 files changed, 208 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/s390x-softmmu.mak
 create mode 100644 target-s390x/machine.c

diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
new file mode 100644
index 0000000..e69de29
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f45b00c..a74745c 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -30,8 +30,7 @@
 
 #include "softfloat.h"
 
-#define NB_MMU_MODES 2 // guess
-#define MMU_USER_IDX 0 // guess
+#define NB_MMU_MODES 2
 
 typedef union FPReg {
     struct {
@@ -77,6 +76,15 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
 }
 #endif
 
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    /* XXX: Currently we don't implement virtual memory */
+    return 0;
+}
+
 CPUS390XState *cpu_s390x_init(const char *cpu_model);
 int cpu_s390x_exec(CPUS390XState *s);
 void cpu_s390x_close(CPUS390XState *s);
@@ -92,6 +100,13 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
 
 #define TARGET_PAGE_BITS 12
 
+#ifndef CONFIG_USER_ONLY
+extern int s390_virtio_hypercall(CPUState *env);
+extern void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token);
+extern CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
+#endif
+
+
 #define cpu_init cpu_s390x_init
 #define cpu_exec cpu_s390x_exec
 #define cpu_gen_code cpu_s390x_gen_code
@@ -116,4 +131,138 @@ static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
     *cs_base = 0;
     *flags = env->psw.mask; // guess
 }
+
+/* Program Status Word.  */
+#define S390_PSWM_REGNUM 0
+#define S390_PSWA_REGNUM 1
+/* General Purpose Registers.  */
+#define S390_R0_REGNUM 2
+#define S390_R1_REGNUM 3
+#define S390_R2_REGNUM 4
+#define S390_R3_REGNUM 5
+#define S390_R4_REGNUM 6
+#define S390_R5_REGNUM 7
+#define S390_R6_REGNUM 8
+#define S390_R7_REGNUM 9
+#define S390_R8_REGNUM 10
+#define S390_R9_REGNUM 11
+#define S390_R10_REGNUM 12
+#define S390_R11_REGNUM 13
+#define S390_R12_REGNUM 14
+#define S390_R13_REGNUM 15
+#define S390_R14_REGNUM 16
+#define S390_R15_REGNUM 17
+/* Access Registers.  */
+#define S390_A0_REGNUM 18
+#define S390_A1_REGNUM 19
+#define S390_A2_REGNUM 20
+#define S390_A3_REGNUM 21
+#define S390_A4_REGNUM 22
+#define S390_A5_REGNUM 23
+#define S390_A6_REGNUM 24
+#define S390_A7_REGNUM 25
+#define S390_A8_REGNUM 26
+#define S390_A9_REGNUM 27
+#define S390_A10_REGNUM 28
+#define S390_A11_REGNUM 29
+#define S390_A12_REGNUM 30
+#define S390_A13_REGNUM 31
+#define S390_A14_REGNUM 32
+#define S390_A15_REGNUM 33
+/* Floating Point Control Word.  */
+#define S390_FPC_REGNUM 34
+/* Floating Point Registers.  */
+#define S390_F0_REGNUM 35
+#define S390_F1_REGNUM 36
+#define S390_F2_REGNUM 37
+#define S390_F3_REGNUM 38
+#define S390_F4_REGNUM 39
+#define S390_F5_REGNUM 40
+#define S390_F6_REGNUM 41
+#define S390_F7_REGNUM 42
+#define S390_F8_REGNUM 43
+#define S390_F9_REGNUM 44
+#define S390_F10_REGNUM 45
+#define S390_F11_REGNUM 46
+#define S390_F12_REGNUM 47
+#define S390_F13_REGNUM 48
+#define S390_F14_REGNUM 49
+#define S390_F15_REGNUM 50
+/* Total.  */
+#define S390_NUM_REGS 51
+
+/* Pseudo registers -- PC and condition code.  */
+#define S390_PC_REGNUM S390_NUM_REGS
+#define S390_CC_REGNUM (S390_NUM_REGS+1)
+#define S390_NUM_PSEUDO_REGS 2
+#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+
+
+
+/* Program Status Word.  */
+#define S390_PSWM_REGNUM 0
+#define S390_PSWA_REGNUM 1
+/* General Purpose Registers.  */
+#define S390_R0_REGNUM 2
+#define S390_R1_REGNUM 3
+#define S390_R2_REGNUM 4
+#define S390_R3_REGNUM 5
+#define S390_R4_REGNUM 6
+#define S390_R5_REGNUM 7
+#define S390_R6_REGNUM 8
+#define S390_R7_REGNUM 9
+#define S390_R8_REGNUM 10
+#define S390_R9_REGNUM 11
+#define S390_R10_REGNUM 12
+#define S390_R11_REGNUM 13
+#define S390_R12_REGNUM 14
+#define S390_R13_REGNUM 15
+#define S390_R14_REGNUM 16
+#define S390_R15_REGNUM 17
+/* Access Registers.  */
+#define S390_A0_REGNUM 18
+#define S390_A1_REGNUM 19
+#define S390_A2_REGNUM 20
+#define S390_A3_REGNUM 21
+#define S390_A4_REGNUM 22
+#define S390_A5_REGNUM 23
+#define S390_A6_REGNUM 24
+#define S390_A7_REGNUM 25
+#define S390_A8_REGNUM 26
+#define S390_A9_REGNUM 27
+#define S390_A10_REGNUM 28
+#define S390_A11_REGNUM 29
+#define S390_A12_REGNUM 30
+#define S390_A13_REGNUM 31
+#define S390_A14_REGNUM 32
+#define S390_A15_REGNUM 33
+/* Floating Point Control Word.  */
+#define S390_FPC_REGNUM 34
+/* Floating Point Registers.  */
+#define S390_F0_REGNUM 35
+#define S390_F1_REGNUM 36
+#define S390_F2_REGNUM 37
+#define S390_F3_REGNUM 38
+#define S390_F4_REGNUM 39
+#define S390_F5_REGNUM 40
+#define S390_F6_REGNUM 41
+#define S390_F7_REGNUM 42
+#define S390_F8_REGNUM 43
+#define S390_F9_REGNUM 44
+#define S390_F10_REGNUM 45
+#define S390_F11_REGNUM 46
+#define S390_F12_REGNUM 47
+#define S390_F13_REGNUM 48
+#define S390_F14_REGNUM 49
+#define S390_F15_REGNUM 50
+/* Total.  */
+#define S390_NUM_REGS 51
+
+/* Pseudo registers -- PC and condition code.  */
+#define S390_PC_REGNUM S390_NUM_REGS
+#define S390_CC_REGNUM (S390_NUM_REGS+1)
+#define S390_NUM_PSEUDO_REGS 2
+#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+
+
 #endif
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index 5198359..13dc7dd 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -22,9 +22,14 @@
 
 register struct CPUS390XState *env asm(AREG0);
 
+#include "config.h"
 #include "cpu.h"
 #include "exec-all.h"
 
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif /* !defined(CONFIG_USER_ONLY) */
+
 static inline int cpu_has_work(CPUState *env)
 {
     return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 0e222e3..f4c4e04 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -27,6 +27,9 @@
 #include "gdbstub.h"
 #include "qemu-common.h"
 
+#include <linux/kvm.h>
+#include "kvm.h"
+
 CPUS390XState *cpu_s390x_init(const char *cpu_model)
 {
     CPUS390XState *env;
@@ -60,3 +63,22 @@ void cpu_reset(CPUS390XState *env)
     /* FIXME: reset vector? */
     tlb_flush(env, 1);
 }
+
+#ifndef CONFIG_USER_ONLY
+
+int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+                                int mmu_idx, int is_softmmu)
+{
+    target_ulong phys;
+    int prot;
+
+    /* XXX: implement mmu */
+
+    phys = address;
+    prot = PAGE_READ | PAGE_WRITE;
+
+    return tlb_set_page(env, address & TARGET_PAGE_MASK,
+                        phys & TARGET_PAGE_MASK, prot,
+                        mmu_idx, is_softmmu);
+}
+#endif /* CONFIG_USER_ONLY */
diff --git a/target-s390x/machine.c b/target-s390x/machine.c
new file mode 100644
index 0000000..3e79be6
--- /dev/null
+++ b/target-s390x/machine.c
@@ -0,0 +1,30 @@
+/*
+ * QEMU S390x machine definitions
+ *
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/hw.h"
+#include "hw/boards.h"
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+    return 0;
+}
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 07/13] Add S390x virtio machine bus
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (5 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 08/13] Add S390x virtio machine description Alexander Graf
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

On S390x we don't want to go through the hassle of emulating real existing
hardware, because we don't need to for running Linux.

So let's instead implement a machine that is 100% based on VirtIO which we
fortunately implement already.

This patch implements the bus that is the groundwork for such an S390x
virtio machine.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target      |    2 +
 hw/s390-virtio-bus.c |  385 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/s390-virtio-bus.h |   65 +++++++++
 3 files changed, 452 insertions(+), 0 deletions(-)
 create mode 100644 hw/s390-virtio-bus.c
 create mode 100644 hw/s390-virtio-bus.h

diff --git a/Makefile.target b/Makefile.target
index 91aa4a2..2b9f85d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -297,6 +297,8 @@ obj-sh4-y += ide/core.o ide/mmio.o
 obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 obj-m68k-y += m68k-semi.o dummy_m68k.o
 
+obj-s390x-y = s390-virtio-bus.o
+
 main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
new file mode 100644
index 0000000..c4b6e69
--- /dev/null
+++ b/hw/s390-virtio-bus.c
@@ -0,0 +1,385 @@
+/*
+ * QEMU S390 virtio target
+ *
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw.h"
+#include "block.h"
+#include "sysemu.h"
+#include "net.h"
+#include "boards.h"
+#include "monitor.h"
+#include "loader.h"
+#include "elf.h"
+#include "hw/virtio.h"
+#include "hw/virtio-console.h"
+#include "hw/sysbus.h"
+#include "kvm.h"
+
+#include "hw/s390-virtio-bus.h"
+
+//#define DEBUG_S390
+
+#ifdef DEBUG_S390
+#define dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+struct BusInfo s390_virtio_bus_info = {
+    .name       = "s390-virtio",
+    .size       = sizeof(VirtIOS390Bus),
+};
+
+typedef struct {
+    DeviceInfo qdev;
+    int (*init)(VirtIOS390Device *dev);
+} VirtIOS390DeviceInfo;
+
+
+static const VirtIOBindings virtio_s390_bindings;
+
+static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
+static void s390_virtio_device_sync(VirtIOS390Device *dev);
+
+VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
+{
+    VirtIOS390Bus *bus;
+    BusState *_bus;
+    DeviceState *dev;
+
+    /* Create bridge device */
+    dev = qdev_create(NULL, "s390-virtio-bridge");
+    qdev_init_nofail(dev);
+
+    /* Create bus on bridge device */
+
+    _bus = qbus_create(&s390_virtio_bus_info, dev, "s390-virtio");
+    bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
+
+    bus->dev_page = *ram_size;
+    bus->dev_offs = bus->dev_page;
+    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
+
+    /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
+    *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
+
+    return bus;
+}
+
+static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
+{
+    VirtIOS390Bus *bus;
+    int dev_len;
+
+    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
+    dev->vdev = vdev;
+    dev->dev_offs = bus->dev_offs;
+    dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */
+
+    dev_len = VIRTIO_DEV_OFFS_CONFIG;
+    dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
+    dev_len += dev->feat_len * 2;
+    dev_len += vdev->config_len;
+    
+    bus->dev_offs += dev_len;
+
+    virtio_bind_device(vdev, &virtio_s390_bindings, dev);
+    s390_virtio_device_sync(dev);
+
+    return 0;
+}
+
+static int s390_virtio_net_init(VirtIOS390Device *dev)
+{
+    VirtIODevice *vdev;
+
+    vdev = virtio_net_init((DeviceState *)dev, &dev->nic);
+    if (!vdev)
+        return -1;
+
+    return s390_virtio_device_init(dev, vdev);
+}
+
+static int s390_virtio_blk_init(VirtIOS390Device *dev)
+{
+    VirtIODevice *vdev;
+
+    vdev = virtio_blk_init((DeviceState *)dev, dev->dinfo);
+    if (!vdev)
+        return -1;
+
+    return s390_virtio_device_init(dev, vdev);
+}
+
+static int s390_virtio_console_init(VirtIOS390Device *dev)
+{
+    VirtIOS390Bus *bus;
+    VirtIODevice *vdev;
+    int r;
+
+    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
+
+    vdev = virtio_console_init((DeviceState *)dev);
+    if (!vdev)
+        return -1;
+
+    r = s390_virtio_device_init(dev, vdev);
+    if (!r)
+        bus->console = dev;
+
+    return r;
+}
+
+static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
+{
+    ram_addr_t token_off;
+
+    token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
+                (vq * VIRTIO_VQCONFIG_LEN) +
+                VIRTIO_VQCONFIG_OFFS_TOKEN;
+
+    return ldq_phys(token_off);
+}
+
+static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
+{
+    VirtIODevice *vdev = dev->vdev;
+    int num_vq;
+
+    for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
+        if (!virtio_queue_get_num(vdev, num_vq))
+            break;
+    }
+
+    return num_vq;
+}
+
+static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
+{
+    ram_addr_t r = bus->next_ring;
+
+    bus->next_ring += VIRTIO_RING_LEN;
+    return r;
+}
+
+static void s390_virtio_device_sync(VirtIOS390Device *dev)
+{
+    VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
+    ram_addr_t cur_offs;
+    uint8_t num_vq;
+    int i;
+
+    virtio_reset(dev->vdev);
+
+    /* Sync dev space */
+    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
+
+    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, s390_virtio_device_num_vq(dev));
+    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
+
+    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
+
+    num_vq = s390_virtio_device_num_vq(dev);
+    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
+
+    /* Sync virtqueues */
+    for (i = 0; i < num_vq; i++) {
+        ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
+                        (i * VIRTIO_VQCONFIG_LEN);
+        ram_addr_t vring;
+
+        vring = s390_virtio_next_ring(bus);
+        virtio_queue_set_addr(dev->vdev, i, vring);
+        virtio_queue_set_vector(dev->vdev, i, i);
+        stq_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
+        stw_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
+    }
+
+    cur_offs = dev->dev_offs;
+    cur_offs += VIRTIO_DEV_OFFS_CONFIG;
+    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
+
+    /* Sync feature bitmap */
+    if (dev->vdev->get_features)
+        stl_phys(cur_offs, dev->vdev->get_features(dev->vdev));
+
+    dev->feat_offs = cur_offs + dev->feat_len;
+    cur_offs += dev->feat_len * 2;
+
+    /* Sync config space */
+    if (dev->vdev->get_config)
+        dev->vdev->get_config(dev->vdev, dev->vdev->config);
+
+    cpu_physical_memory_rw(cur_offs, dev->vdev->config, dev->vdev->config_len, 1);
+    cur_offs += dev->vdev->config_len;
+}
+
+void s390_virtio_device_update_status(VirtIOS390Device *dev)
+{
+    VirtIODevice *vdev = dev->vdev;
+    uint32_t features;
+
+    vdev->status = ldub_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS);
+
+    /* Update guest supported feature bitmap */
+
+    features = ldl_phys(dev->feat_offs);
+    if (vdev->set_features)
+        vdev->set_features(vdev, features);
+    vdev->features = features;
+}
+
+VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
+{
+    return bus->console;
+}
+
+/* Find a device by vring address */
+VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
+                                             ram_addr_t mem,
+                                             int *vq_num)
+{
+    VirtIOS390Device *_dev;
+    DeviceState *dev;
+    int i;
+
+    QLIST_FOREACH(dev, &bus->bus.children, sibling) {
+        _dev = (VirtIOS390Device *)dev;
+        for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
+            if (!virtio_queue_get_addr(_dev->vdev, i))
+                break;
+            if (virtio_queue_get_addr(_dev->vdev, i) == mem) {
+                if (vq_num) *vq_num = i;
+                return _dev;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+/* Find a device by device descriptor location */
+VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
+{
+    VirtIOS390Device *_dev;
+    DeviceState *dev;
+
+    QLIST_FOREACH(dev, &bus->bus.children, sibling) {
+        _dev = (VirtIOS390Device *)dev;
+        if (_dev->dev_offs == mem) {
+            return _dev;
+        }
+    }
+
+    return NULL;
+}
+
+static void virtio_s390_notify(void *opaque, uint16_t vector)
+{
+    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
+    uint64_t token = s390_virtio_device_vq_token(dev, vector);
+
+    /* XXX kvm dependency! */
+    kvm_s390_virtio_irq(s390_cpu_addr2state(0), 1, token);
+}
+
+/**************** S390 Virtio Bus Device Descriptions *******************/
+
+static const VirtIOBindings virtio_s390_bindings = {
+    .notify = virtio_s390_notify,
+};
+
+static VirtIOS390DeviceInfo s390_virtio_net = {
+    .init = s390_virtio_net_init,
+    .qdev.name = "virtio-net-s390",
+    .qdev.size = sizeof(VirtIOS390Device),
+    .qdev.props = (Property[]) {
+        DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static VirtIOS390DeviceInfo s390_virtio_blk = {
+    .init = s390_virtio_blk_init,
+    .qdev.name = "virtio-blk-s390",
+    .qdev.size = sizeof(VirtIOS390Device),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_DRIVE("drive", VirtIOS390Device, dinfo),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static VirtIOS390DeviceInfo s390_virtio_console = {
+    .init = s390_virtio_console_init,
+    .qdev.name = "virtio-console-s390",
+    .qdev.size = sizeof(VirtIOS390Device),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
+{
+    VirtIOS390DeviceInfo *_info = (VirtIOS390DeviceInfo *)info;
+    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
+
+    return _info->init(_dev);
+}
+
+static void s390_virtio_bus_register_withprop(VirtIOS390DeviceInfo *info)
+{
+    info->qdev.init = s390_virtio_busdev_init;
+    info->qdev.bus_info = &s390_virtio_bus_info;
+
+    assert(info->qdev.size >= sizeof(VirtIOS390Device));
+    qdev_register(&info->qdev);
+}
+
+static void s390_virtio_register(void)
+{
+    s390_virtio_bus_register_withprop(&s390_virtio_console);
+    s390_virtio_bus_register_withprop(&s390_virtio_blk);
+    s390_virtio_bus_register_withprop(&s390_virtio_net);
+}
+device_init(s390_virtio_register);
+
+
+/***************** S390 Virtio Bus Bridge Device *******************/
+/* Only required to have the virtio bus as child in the system bus */
+
+static int s390_virtio_bridge_init(SysBusDevice *dev)
+{
+    /* nothing */
+    return 0;
+}
+
+static SysBusDeviceInfo s390_virtio_bridge_info = {
+    .init = s390_virtio_bridge_init,
+    .qdev.name  = "s390-virtio-bridge",
+    .qdev.size  = sizeof(SysBusDevice),
+    .qdev.no_user = 1,
+};
+
+static void s390_virtio_register_devices(void)
+{
+    sysbus_register_withprop(&s390_virtio_bridge_info);
+}
+
+device_init(s390_virtio_register_devices)
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
new file mode 100644
index 0000000..e84fd64
--- /dev/null
+++ b/hw/s390-virtio-bus.h
@@ -0,0 +1,65 @@
+/*
+ * QEMU S390x VirtIO BUS definitions
+ *
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#define VIRTIO_DEV_OFFS_TYPE		0	/* 8 bits */
+#define VIRTIO_DEV_OFFS_NUM_VQ		1	/* 8 bits */
+#define VIRTIO_DEV_OFFS_FEATURE_LEN	2	/* 8 bits */
+#define VIRTIO_DEV_OFFS_CONFIG_LEN	3	/* 8 bits */
+#define VIRTIO_DEV_OFFS_STATUS		4	/* 8 bits */
+#define VIRTIO_DEV_OFFS_CONFIG		5	/* dynamic */
+
+#define VIRTIO_VQCONFIG_OFFS_TOKEN	0	/* 64 bits */
+#define VIRTIO_VQCONFIG_OFFS_ADDRESS	8	/* 64 bits */
+#define VIRTIO_VQCONFIG_OFFS_NUM	16	/* 16 bits */
+#define VIRTIO_VQCONFIG_LEN		24
+
+#define VIRTIO_RING_LEN			(TARGET_PAGE_SIZE * 3)
+#define S390_DEVICE_PAGES		256
+
+typedef struct VirtIOS390Device {
+    DeviceState qdev;
+    ram_addr_t dev_offs;
+    ram_addr_t feat_offs;
+    uint8_t feat_len;
+    VirtIODevice *vdev;
+    DriveInfo *dinfo;
+    NICConf nic;
+} VirtIOS390Device;
+
+typedef struct VirtIOS390Bus {
+    BusState bus;
+
+    VirtIOS390Device *console;
+    ram_addr_t dev_page;
+    ram_addr_t dev_offs;
+    ram_addr_t next_ring;
+} VirtIOS390Bus;
+
+
+extern void s390_virtio_device_update_status(VirtIOS390Device *dev);
+
+extern VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus);
+extern VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size);
+
+extern VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
+                                                    ram_addr_t mem,
+                                                    int *vq_num);
+extern VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus,
+                                                  ram_addr_t mem);
+
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 08/13] Add S390x virtio machine description
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (6 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 07/13] Add S390x virtio machine bus Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 09/13] S390 GDB stub Alexander Graf
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

In order to use the new S390x virtio bus we just introduced, we also
need a machine description that sets up the machine according to our
PV specification.

Let's add that machine description and be happy!

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target  |    2 +-
 hw/s390-virtio.c |  243 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 244 insertions(+), 1 deletions(-)
 create mode 100644 hw/s390-virtio.c

diff --git a/Makefile.target b/Makefile.target
index 2b9f85d..d47d879 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -297,7 +297,7 @@ obj-sh4-y += ide/core.o ide/mmio.o
 obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 obj-m68k-y += m68k-semi.o dummy_m68k.o
 
-obj-s390x-y = s390-virtio-bus.o
+obj-s390x-y = s390-virtio-bus.o s390-virtio.o 
 
 main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
new file mode 100644
index 0000000..c843e0d
--- /dev/null
+++ b/hw/s390-virtio.c
@@ -0,0 +1,243 @@
+/*
+ * QEMU S390 virtio target
+ *
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw.h"
+#include "block.h"
+#include "sysemu.h"
+#include "net.h"
+#include "boards.h"
+#include "monitor.h"
+#include "loader.h"
+#include "elf.h"
+#include "hw/virtio.h"
+#include "hw/virtio-console.h"
+#include "hw/sysbus.h"
+#include "kvm.h"
+
+#include "hw/s390-virtio-bus.h"
+
+//#define DEBUG_S390
+
+#ifdef DEBUG_S390
+#define dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+#define KVM_S390_VIRTIO_NOTIFY          0
+#define KVM_S390_VIRTIO_RESET           1
+#define KVM_S390_VIRTIO_SET_STATUS      2
+
+#define KERN_IMAGE_START                0x010000UL
+#define KERN_PARM_AREA                  0x010480UL
+#define INITRD_START                    0x800000UL
+#define INITRD_PARM_START               0x010408UL
+#define INITRD_PARM_SIZE                0x010410UL
+#define PARMFILE_START                  0x001000UL
+
+#define MAX_BLK_DEVS                    10
+
+static VirtIOS390Bus *s390_bus;
+static CPUState **ipi_states;
+
+void irq_info(Monitor *mon);
+void pic_info(Monitor *mon);
+
+void irq_info(Monitor *mon)
+{
+}
+
+void pic_info(Monitor *mon)
+{
+}
+
+CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
+{
+    if (cpu_addr >= smp_cpus)
+        return NULL;
+
+    return ipi_states[cpu_addr];
+}
+
+int s390_virtio_hypercall(CPUState *env)
+{
+    int r = 0, i;
+    target_ulong mem = env->regs[2];
+
+    dprintf("KVM hypercall: %ld\n", env->regs[1]);
+    switch (env->regs[1]) {
+    case KVM_S390_VIRTIO_NOTIFY:
+        if (mem > ram_size) {
+            VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
+                                                               mem, &i);
+            if (dev) {
+                virtio_queue_notify(dev->vdev, i);
+            } else {
+                r = -EINVAL;
+            }
+        } else {
+            /* Early printk */
+            uint8_t *p = (uint8_t *)qemu_get_ram_ptr(mem);
+            VirtIOS390Device *dev = s390_virtio_bus_console(s390_bus);
+            virtio_console_print_early(dev->vdev, p);
+        }
+        break;
+    case KVM_S390_VIRTIO_RESET:
+    {
+        /* Virtio_reset resets the internal addresses, so we'd have to sync
+           them up again. We don't want to reallicate a vring though, so let's
+           just not reset. */
+        /* virtio_reset(dev->vdev); */
+        break;
+    }
+    case KVM_S390_VIRTIO_SET_STATUS:
+    {
+        VirtIOS390Device *dev;
+
+        dev = s390_virtio_bus_find_mem(s390_bus, mem);
+        if (dev)
+            s390_virtio_device_update_status(dev);
+        else
+            r = -EINVAL;
+        break;
+    }
+    default:
+        r = -EINVAL;
+        break;
+    }
+
+    env->regs[2] = r;
+    return 0;
+}
+
+/* PC hardware initialisation */
+static void s390_init(ram_addr_t _ram_size,
+                      const char *boot_device,
+                      const char *kernel_filename,
+                      const char *kernel_cmdline,
+                      const char *initrd_filename,
+                      const char *cpu_model)
+{
+    CPUState *env = NULL;
+    ram_addr_t ram_addr, ram_size = _ram_size;
+    ram_addr_t kernel_size = 0;
+    ram_addr_t initrd_offset;
+    ram_addr_t initrd_size = 0;
+    int i;
+
+    /* get a BUS */
+    s390_bus = s390_virtio_bus_init(&ram_size);
+
+    /* allocate RAM */
+    ram_addr = qemu_ram_alloc(ram_size);
+    cpu_register_physical_memory(0, ram_size, ram_addr);
+
+    /* init CPUs */
+    if (cpu_model == NULL) {
+        cpu_model = "host";
+    }
+
+    ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus);
+
+    for (i = 0; i < smp_cpus; i++) {
+        env = cpu_init(cpu_model);
+        ipi_states[smp_cpus - (i + 1)] = env;
+        env->halted = 1;
+        env->exception_index = EXCP_HLT;
+    }
+
+    env->halted = 0;
+    env->exception_index = 0;
+
+    if (kernel_filename) {
+        kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
+
+        if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
+            fprintf(stderr, "Specified image is not an s390 boot image\n");
+            exit(1);
+        }
+
+        cpu_synchronize_state(env);
+        env->psw.addr = KERN_IMAGE_START;
+        env->psw.mask = 0x0000000180000000UL;
+    }
+
+    if (initrd_filename) {
+        initrd_offset = INITRD_START;
+        while (kernel_size + 0x100000 > initrd_offset)
+            initrd_offset += 0x100000;
+        initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));
+
+        stq_phys(INITRD_PARM_START, initrd_offset);
+        stq_phys(INITRD_PARM_SIZE, initrd_size);
+    }
+
+    if (kernel_cmdline) {
+        cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline,
+                               strlen(kernel_cmdline), 1);
+    }
+
+    /* Create VirtIO console */
+    qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390"));
+
+    /* Create VirtIO network adapters */
+    for(i = 0; i < nb_nics; i++) {
+        NICInfo *nd = &nd_table[i];
+        DeviceState *dev;
+
+        if (!nd->model)
+            nd->model = (char*)"virtio";
+
+        dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
+        qdev_set_nic_properties(dev, nd);
+        qdev_init_nofail(dev);
+    }
+
+    /* Create VirtIO disk drives */
+    for(i = 0; i < MAX_BLK_DEVS; i++) {
+        DriveInfo *dinfo;
+        DeviceState *dev;
+
+        dinfo = drive_get(IF_IDE, 0, i);
+        if (!dinfo)
+            continue;
+
+        dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
+        qdev_prop_set_drive(dev, "drive", dinfo);
+        qdev_init_nofail(dev);
+    }
+}
+
+static QEMUMachine s390_machine = {
+    .name = "s390-virtio",
+    .alias = "s390",
+    .desc = "VirtIO based S390 machine",
+    .init = s390_init,
+    .max_cpus = 255,
+    .is_default = 1,
+};
+
+static void s390_machine_init(void)
+{
+    qemu_register_machine(&s390_machine);
+}
+
+machine_init(s390_machine_init);
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 09/13] S390 GDB stub
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (7 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 08/13] Add S390x virtio machine description Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console Alexander Graf
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

In order to debug funny kernel breakages it's always good to have a working
gdb stub around.

While Uli's patches don't include one one, I needed one that's at least good
enough for 'bt' and some variable examinations during early bootup.

So here it is - the absolute basics to get the qemu gdb stub running with s390x
targets.

Sgined-off-by: Alexander Graf <agraf@suse.de>
---
 gdbstub.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 055093f..1ba6ad0 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1348,6 +1348,55 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
 
     return 8;
 }
+#elif defined (TARGET_S390X)
+
+#define NUM_CORE_REGS S390_NUM_TOTAL_REGS
+
+static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+    switch (n) {
+        case S390_PSWM_REGNUM: GET_REGL(env->psw.mask); break;
+        case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); break;
+        case S390_R0_REGNUM ... S390_R15_REGNUM:
+            GET_REGL(env->regs[n-S390_R0_REGNUM]); break;
+        case S390_A0_REGNUM ... S390_A15_REGNUM:
+            GET_REG32(env->aregs[n-S390_A0_REGNUM]); break;
+        case S390_FPC_REGNUM: GET_REG32(env->fpc); break;
+        case S390_F0_REGNUM ... S390_F15_REGNUM:
+            /* XXX */
+            break;
+        case S390_PC_REGNUM: GET_REGL(env->psw.addr); break;
+        case S390_CC_REGNUM: GET_REG32(env->cc); break;
+    }
+
+    return 0;
+}
+
+static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+    target_ulong tmpl;
+    uint32_t tmp32;
+    int r = 8;
+    tmpl = ldtul_p(mem_buf);
+    tmp32 = ldl_p(mem_buf);
+
+    switch (n) {
+        case S390_PSWM_REGNUM: env->psw.mask = tmpl; break;
+        case S390_PSWA_REGNUM: env->psw.addr = tmpl; break;
+        case S390_R0_REGNUM ... S390_R15_REGNUM:
+            env->regs[n-S390_R0_REGNUM] = tmpl; break;
+        case S390_A0_REGNUM ... S390_A15_REGNUM:
+            env->aregs[n-S390_A0_REGNUM] = tmp32; r=4; break;
+        case S390_FPC_REGNUM: env->fpc = tmp32; r=4; break;
+        case S390_F0_REGNUM ... S390_F15_REGNUM:
+            /* XXX */
+            break;
+        case S390_PC_REGNUM: env->psw.addr = tmpl; break;
+        case S390_CC_REGNUM: env->cc = tmp32; r=4; break;
+    }
+
+    return r;
+}
 #else
 
 #define NUM_CORE_REGS 0
@@ -1616,6 +1665,9 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
     s->c_cpu->pc = pc;
 #elif defined (TARGET_ALPHA)
     s->c_cpu->pc = pc;
+#elif defined (TARGET_S390X)
+    cpu_synchronize_state(s->c_cpu);
+    s->c_cpu->psw.addr = pc;
 #endif
 }
 
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (8 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 09/13] S390 GDB stub Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 18:55   ` Anthony Liguori
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 11/13] Set default console to virtio on S390x Alexander Graf
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

On our S390x Virtio machine we don't have anywhere to display early printks
on, because we don't know about VGA or serial ports.

So instead we just forward everything to the virtio console that we created
anyways.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/virtio-console.c |    7 +++++++
 hw/virtio-console.h |    2 ++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 57f8f89..cd6cf20 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -105,6 +105,13 @@ static void vcon_event(void *opaque, int event)
     /* we will ignore any event for the time being */
 }
 
+void virtio_console_print_early(VirtIODevice *vdev, uint8_t *buf)
+{
+    VirtIOConsole *s = to_virtio_console(vdev);
+
+    qemu_chr_write(s->chr, buf, strlen((char*)buf));
+}
+
 static void virtio_console_save(QEMUFile *f, void *opaque)
 {
     VirtIOConsole *s = opaque;
diff --git a/hw/virtio-console.h b/hw/virtio-console.h
index 84d0717..f3ccc3c 100644
--- a/hw/virtio-console.h
+++ b/hw/virtio-console.h
@@ -16,4 +16,6 @@
 /* The ID for virtio console */
 #define VIRTIO_ID_CONSOLE 3
 
+void virtio_console_print_early(VirtIODevice *vdev, uint8_t *buf);
+
 #endif
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 11/13] Set default console to virtio on S390x
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (9 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter Alexander Graf
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 13/13] Add S390 maintainer information Alexander Graf
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

All "normal" system emulation targets in qemu I'm aware of display output
on either VGA or serial output.

Our S390x virtio machine doesn't have such kind of legacy hardware. So
instead we need to default to a virtio console.

I'm not particularly proud of this patch. It would be a lot better to
have something in the machine description that tells us about the default
terminal.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 vl.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/vl.c b/vl.c
index c3f3c8f..46d9e01 100644
--- a/vl.c
+++ b/vl.c
@@ -4663,6 +4663,20 @@ int main(int argc, char **argv, char **envp)
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
 
+#ifdef TARGET_S390X
+    for(i = 0; i < MAX_SERIAL_PORTS; i++)
+        serial_devices[i] = NULL;
+    serial_device_index = 0;
+
+    for(i = 0; i < MAX_PARALLEL_PORTS; i++)
+        parallel_devices[i] = NULL;
+    parallel_device_index = 0;
+
+    virtio_consoles[0] = "mon:stdio";
+    for(i = 1; i < MAX_VIRTIO_CONSOLES; i++)
+        virtio_consoles[i] = NULL;
+    virtio_console_index = 0;
+#else
     serial_devices[0] = "vc:80Cx24C";
     for(i = 1; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i] = NULL;
@@ -4676,6 +4690,7 @@ int main(int argc, char **argv, char **envp)
     for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
         virtio_consoles[i] = NULL;
     virtio_console_index = 0;
+#endif
 
     monitor_devices[0] = "vc:80Cx24C";
     for (i = 1; i < MAX_MONITOR_DEVICES; i++) {
@@ -5587,6 +5602,17 @@ int main(int argc, char **argv, char **envp)
                 break;
             }
         }
+        for (i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
+            const char *devname = virtio_consoles[i];
+            if (devname && !strcmp(devname,"mon:stdio")) {
+                monitor_devices[0] = NULL;
+                break;
+            } else if (devname && !strcmp(devname,"stdio")) {
+                monitor_devices[0] = NULL;
+                virtio_consoles[i] = "mon:stdio";
+                break;
+            }
+        }
     }
 
     if (nb_numa_nodes > 0) {
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (10 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 11/13] Set default console to virtio on S390x Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  2009-11-24 18:53   ` Anthony Liguori
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 13/13] Add S390 maintainer information Alexander Graf
  12 siblings, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

The default bootloader on S390 is zipl. Because we don't emulate normal S390
hardware we need to write our own parser for the bootloader configuration,
so we can boot off real hard disks.

This patch adds a pretty simple implementation of such an interpreter. It only
supports 512 bytes sector sizes, always boots the default entry and doesn't
work with reboots yet. But it's better than nothing.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target    |    2 +-
 hw/s390-virtio.c   |   11 ++-
 hw/s390-zipl.c     |  233 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu.h |    1 +
 4 files changed, 243 insertions(+), 4 deletions(-)
 create mode 100644 hw/s390-zipl.c

diff --git a/Makefile.target b/Makefile.target
index d47d879..e147e09 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -297,7 +297,7 @@ obj-sh4-y += ide/core.o ide/mmio.o
 obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 obj-m68k-y += m68k-semi.o dummy_m68k.o
 
-obj-s390x-y = s390-virtio-bus.o s390-virtio.o 
+obj-s390x-y = s390-virtio-bus.o s390-virtio.o s390-zipl.o
 
 main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index c843e0d..a008c45 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -29,6 +29,7 @@
 #include "hw/virtio-console.h"
 #include "hw/sysbus.h"
 #include "kvm.h"
+#include "s390-zipl.h"
 
 #include "hw/s390-virtio-bus.h"
 
@@ -166,6 +167,7 @@ static void s390_init(ram_addr_t _ram_size,
 
     env->halted = 0;
     env->exception_index = 0;
+    cpu_synchronize_state(env);
 
     if (kernel_filename) {
         kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
@@ -175,9 +177,7 @@ static void s390_init(ram_addr_t _ram_size,
             exit(1);
         }
 
-        cpu_synchronize_state(env);
-        env->psw.addr = KERN_IMAGE_START;
-        env->psw.mask = 0x0000000180000000UL;
+        env->reset_addr = KERN_IMAGE_START;
     }
 
     if (initrd_filename) {
@@ -223,7 +223,12 @@ static void s390_init(ram_addr_t _ram_size,
         dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
         qdev_prop_set_drive(dev, "drive", dinfo);
         qdev_init_nofail(dev);
+
+        zipl_load(env, dinfo->bdrv);
     }
+
+    env->psw.mask = 0x0000000180000000UL;
+    env->psw.addr = env->reset_addr;
 }
 
 static QEMUMachine s390_machine = {
diff --git a/hw/s390-zipl.c b/hw/s390-zipl.c
new file mode 100644
index 0000000..44c08c2
--- /dev/null
+++ b/hw/s390-zipl.c
@@ -0,0 +1,233 @@
+/*
+ * QEMU S390 zipl interpreter
+ *
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw.h"
+#include "block.h"
+#include "sysemu.h"
+#include "net.h"
+#include "boards.h"
+#include "monitor.h"
+#include "loader.h"
+#include "elf.h"
+#include "hw/virtio.h"
+#include "hw/virtio-console.h"
+#include "hw/sysbus.h"
+#include "kvm.h"
+#include "s390-zipl.h"
+
+#include "hw/s390-virtio-bus.h"
+
+//#define DEBUG_S390
+
+#ifdef DEBUG_S390
+#define dprintf(fmt, ...) \
+    do { fprintf(stderr, "zipl: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+struct scsi_blockptr {
+    uint64_t blockno;
+    uint16_t size;
+    uint16_t blockct;
+    uint8_t reserved[4];
+} __attribute__ ((packed));
+
+struct component_entry {
+    struct scsi_blockptr data;
+    uint8_t pad[7];
+    uint8_t component_type;
+    uint64_t load_address;
+} __attribute((packed));
+
+struct component_header {
+    uint8_t magic[4];
+    uint8_t type;
+    uint8_t reserved[27];
+} __attribute((packed));
+
+struct mbr {
+    uint8_t magic[4];
+    uint32_t version_id;
+    uint8_t reserved[8];
+    struct scsi_blockptr blockptr;
+} __attribute__ ((packed));
+
+#define ZIPL_MAGIC			"zIPL"
+#define SECTOR_SIZE			512
+
+#define ZIPL_COMP_HEADER_IPL		0x00
+#define ZIPL_COMP_HEADER_DUMP		0x01
+
+#define ZIPL_COMP_ENTRY_LOAD		0x02
+#define ZIPL_COMP_ENTRY_EXEC		0x01
+
+/* Check for ZIPL magic. Returns 0 if not matched. */
+static int zipl_magic(uint8_t *ptr)
+{
+    int r;
+
+    r = !memcmp(ptr, ZIPL_MAGIC, 4);
+    if (!r)
+        dprintf("invalid magic: %#hhx %#hhx %#hhx %#hhx\n",
+                ptr[0], ptr[1], ptr[2], ptr[3]);
+
+    return r;
+}
+
+static int zipl_load_segment(BlockDriverState *bdrv,
+                             struct component_entry *entry)
+{
+    int max_entries = SECTOR_SIZE / sizeof(struct scsi_blockptr);
+    struct scsi_blockptr bprs[max_entries + 1];
+    uint64_t blockno, address;
+    int i, len;
+    uint8_t *tmp;
+
+    blockno = be64_to_cpu(entry->data.blockno);
+    address = be64_to_cpu(entry->load_address);
+
+    dprintf("loading segment at %#lx : %#lx\n", blockno, address);
+
+    do {
+        if (bdrv_read(bdrv, blockno, (uint8_t *)&bprs, 1) == -1) {
+            dprintf("failed reading bprs at %#lx\n", blockno);
+            goto fail;
+        }
+
+        for (i = 0; i < max_entries; i++) {
+            blockno = be64_to_cpu(bprs[i].blockno);
+            if (!blockno)
+                break;
+
+            len = be16_to_cpu(bprs[i].size) *
+                  (be16_to_cpu(bprs[i].blockct) + 1);
+            tmp = qemu_malloc(len);
+            if (bdrv_pread(bdrv, blockno * SECTOR_SIZE, tmp, len) == -1) {
+                dprintf("failed reading %#x b segment at %#lx\n",
+                        len, blockno * SECTOR_SIZE);
+                qemu_free(tmp);
+                goto fail;
+            }
+
+            cpu_physical_memory_write(address, tmp, len);
+            qemu_free(tmp);
+            address += len;
+        }
+    } while (blockno);
+
+    return 0;
+
+fail:
+    dprintf("failed loading segment\n");
+    return -1;
+}
+
+/* Run a zipl program */
+static int zipl_run(CPUState *env, BlockDriverState *bdrv, struct scsi_blockptr *pte)
+{
+    struct component_header *header;
+    struct component_entry *entry;
+    uint8_t sec[SECTOR_SIZE];
+
+    bdrv_read(bdrv, be64_to_cpu(pte->blockno), sec, 1);
+    header = (struct component_header *)sec;
+
+    if (!zipl_magic(sec))
+        goto fail;
+
+    if (header->type != ZIPL_COMP_HEADER_IPL)
+        goto fail;
+
+    dprintf("start loading images\n");
+
+    /* Load image(s) into RAM */
+    entry = (struct component_entry *)(&header[1]);
+    while (entry->component_type == ZIPL_COMP_ENTRY_LOAD) {
+        if (zipl_load_segment(bdrv, entry) < 0)
+            goto fail;
+
+        entry++;
+
+        if ((uint8_t*)(&entry[1]) > (sec + SECTOR_SIZE))
+            goto fail;
+    }
+
+    /* And set the reset vector, so we know where to start */
+    if (entry->component_type != ZIPL_COMP_ENTRY_EXEC)
+        goto fail;
+
+    env->reset_addr = be64_to_cpu(entry->load_address) & 0x7fffffff;
+    dprintf("set reset addr to: %#lx\n", env->reset_addr);
+
+    return 0;
+
+fail:
+    dprintf("failed running zipl\n");
+    return -1;
+}
+
+int zipl_load(CPUState *env, BlockDriverState *bdrv)
+{
+    struct mbr mbr;
+    uint8_t sec[SECTOR_SIZE], *ns, *ns_end;
+    int program_table_entries = 0;
+    int pte_len = sizeof(struct scsi_blockptr);
+    struct scsi_blockptr *prog_table_entry;
+
+    /* Grab the MBR */
+
+    if (bdrv_pread(bdrv, 0, &mbr, sizeof(mbr)) == -1)
+        goto fail;
+
+    if (!zipl_magic(mbr.magic))
+        goto fail;
+
+    /* Parse the program table */
+    if (bdrv_read(bdrv, be64_to_cpu(mbr.blockptr.blockno), sec, 1) == -1)
+        goto fail;
+
+    if (!zipl_magic(sec))
+        goto fail;
+
+    ns_end = sec + SECTOR_SIZE;
+    for (ns = (sec + pte_len); (ns + pte_len) < ns_end; ns++) {
+        prog_table_entry = (struct scsi_blockptr *)ns;
+        if (!prog_table_entry->blockno)
+            break;
+
+        program_table_entries++;
+    }
+
+    dprintf("Found %d program table entries\n", program_table_entries);
+
+    if (!program_table_entries)
+        goto fail;
+
+    /* Run the default entry */
+
+    prog_table_entry = (struct scsi_blockptr *)(sec + pte_len);
+
+    return zipl_run(env, bdrv, prog_table_entry);
+
+fail:
+    dprintf("failed loading zipl\n");
+    return -1;
+}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index a74745c..2e286c7 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -63,6 +63,7 @@ typedef struct CPUS390XState {
     int cc; /* condition code (0-3) */
     
     uint64_t __excp_addr;
+    uint64_t reset_addr;
     
     CPU_COMMON
 } CPUS390XState;
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [Qemu-devel] [PATCH 13/13] Add S390 maintainer information
  2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
                   ` (11 preceding siblings ...)
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter Alexander Graf
@ 2009-11-24 17:29 ` Alexander Graf
  12 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 17:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno

This patch adds information about who handles what when it comes to S390.
I'll gladly support anything that's related to the device emulation model and
S390 KVM parts.

Since this patchset doesn't implement S390 CPU emulation, I left that part
with a question mark. As soon as Uli's patchset gets committed I'd recommend
setting him there.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 MAINTAINERS |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d356495..56f107e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20,6 +20,7 @@ SH4                ?
 CRIS               Edgar E. Iglesias
 Alpha              ?
 MicroBlaze         Edgar E. Iglesias
+S390               ?
 
 Machines (sorted by CPU):
 -------------------------
@@ -63,6 +64,8 @@ CRIS
 Alpha
 MicroBlaze
   petalogix_s3adsp1800.c  Edgar E. Iglesias
+S390
+  s390-*.c                Alexander Graf
 
 Generic Subsystems:
 -------------------  
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter Alexander Graf
@ 2009-11-24 18:53   ` Anthony Liguori
  2009-11-24 18:56     ` Alexander Graf
  2009-11-25  8:59     ` Carsten Otte
  0 siblings, 2 replies; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 18:53 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno

Alexander Graf wrote:
> The default bootloader on S390 is zipl. Because we don't emulate normal S390
> hardware we need to write our own parser for the bootloader configuration,
> so we can boot off real hard disks.
>
> This patch adds a pretty simple implementation of such an interpreter. It only
> supports 512 bytes sector sizes, always boots the default entry and doesn't
> work with reboots yet. But it's better than nothing.
>   

This is a bit unfortunate.  Wouldn't it be better to write a custom 
version of zipl that ran in the guest?

This is like implementing grub in qemu (or pygrub in Xen).  The level of 
security exposure this introduces is really scary.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console Alexander Graf
@ 2009-11-24 18:55   ` Anthony Liguori
  2009-11-24 18:56     ` Alexander Graf
  2009-11-25  9:03     ` Carsten Otte
  0 siblings, 2 replies; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 18:55 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno

Alexander Graf wrote:
> On our S390x Virtio machine we don't have anywhere to display early printks
> on, because we don't know about VGA or serial ports.
>
> So instead we just forward everything to the virtio console that we created
> anyways.
>   

What is this used for?

> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  hw/virtio-console.c |    7 +++++++
>  hw/virtio-console.h |    2 ++
>  2 files changed, 9 insertions(+), 0 deletions(-)
>
> diff --git a/hw/virtio-console.c b/hw/virtio-console.c
> index 57f8f89..cd6cf20 100644
> --- a/hw/virtio-console.c
> +++ b/hw/virtio-console.c
> @@ -105,6 +105,13 @@ static void vcon_event(void *opaque, int event)
>      /* we will ignore any event for the time being */
>  }
>  
> +void virtio_console_print_early(VirtIODevice *vdev, uint8_t *buf)
> +{
> +    VirtIOConsole *s = to_virtio_console(vdev);
> +
> +    qemu_chr_write(s->chr, buf, strlen((char*)buf));
> +}
> +
>  static void virtio_console_save(QEMUFile *f, void *opaque)
>  {
>      VirtIOConsole *s = opaque;
> diff --git a/hw/virtio-console.h b/hw/virtio-console.h
> index 84d0717..f3ccc3c 100644
> --- a/hw/virtio-console.h
> +++ b/hw/virtio-console.h
> @@ -16,4 +16,6 @@
>  /* The ID for virtio console */
>  #define VIRTIO_ID_CONSOLE 3
>  
> +void virtio_console_print_early(VirtIODevice *vdev, uint8_t *buf);
> +
>  #endif
>   

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 18:53   ` Anthony Liguori
@ 2009-11-24 18:56     ` Alexander Graf
  2009-11-24 19:26       ` Anthony Liguori
  2009-11-25  8:59     ` Carsten Otte
  1 sibling, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 18:56 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 24.11.2009, at 19:53, Anthony Liguori wrote:

> Alexander Graf wrote:
>> The default bootloader on S390 is zipl. Because we don't emulate normal S390
>> hardware we need to write our own parser for the bootloader configuration,
>> so we can boot off real hard disks.
>> 
>> This patch adds a pretty simple implementation of such an interpreter. It only
>> supports 512 bytes sector sizes, always boots the default entry and doesn't
>> work with reboots yet. But it's better than nothing.
>>  
> 
> This is a bit unfortunate.  Wouldn't it be better to write a custom version of zipl that ran in the guest?

Yeah, I've been struggling quite a bit with this myself. Writing a custom version that runs in the guest means we have to create

1) extboot
2) input backdoor

Or implement virtio in that custom version. That sounds like a pretty huge project.

So I decided to go for the easy way for now and hopefully migrate to an in-guest version later.


Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 18:55   ` Anthony Liguori
@ 2009-11-24 18:56     ` Alexander Graf
  2009-11-24 19:25       ` Anthony Liguori
  2009-11-25  9:03     ` Carsten Otte
  1 sibling, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 18:56 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 24.11.2009, at 19:55, Anthony Liguori wrote:

> Alexander Graf wrote:
>> On our S390x Virtio machine we don't have anywhere to display early printks
>> on, because we don't know about VGA or serial ports.
>> 
>> So instead we just forward everything to the virtio console that we created
>> anyways.
>>  
> 
> What is this used for?

This is used for console output before virtio is initialized. I didn't invent it - that's the way it's implemented in the s390 kernels today.

Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 18:56     ` Alexander Graf
@ 2009-11-24 19:25       ` Anthony Liguori
  2009-11-24 19:27         ` Alexander Graf
  0 siblings, 1 reply; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 19:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno

Alexander Graf wrote:
> On 24.11.2009, at 19:55, Anthony Liguori wrote:
>
>   
>> Alexander Graf wrote:
>>     
>>> On our S390x Virtio machine we don't have anywhere to display early printks
>>> on, because we don't know about VGA or serial ports.
>>>
>>> So instead we just forward everything to the virtio console that we created
>>> anyways.
>>>  
>>>       
>> What is this used for?
>>     
>
> This is used for console output before virtio is initialized. I didn't invent it - that's the way it's implemented in the s390 kernels today.
>   

I don't see any code that calls this function.  Am I missing something 
obvious?

> Alex

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 18:56     ` Alexander Graf
@ 2009-11-24 19:26       ` Anthony Liguori
  2009-11-24 19:29         ` Alexander Graf
  2009-11-25  9:58         ` Carsten Otte
  0 siblings, 2 replies; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 19:26 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno

Alexander Graf wrote:
> On 24.11.2009, at 19:53, Anthony Liguori wrote:
>
>   
>> Alexander Graf wrote:
>>     
>>> The default bootloader on S390 is zipl. Because we don't emulate normal S390
>>> hardware we need to write our own parser for the bootloader configuration,
>>> so we can boot off real hard disks.
>>>
>>> This patch adds a pretty simple implementation of such an interpreter. It only
>>> supports 512 bytes sector sizes, always boots the default entry and doesn't
>>> work with reboots yet. But it's better than nothing.
>>>  
>>>       
>> This is a bit unfortunate.  Wouldn't it be better to write a custom version of zipl that ran in the guest?
>>     
>
> Yeah, I've been struggling quite a bit with this myself. Writing a custom version that runs in the guest means we have to create
>
> 1) extboot
> 2) input backdoor
>
> Or implement virtio in that custom version. That sounds like a pretty huge project.
>
> So I decided to go for the easy way for now and hopefully migrate to an in-guest version later.
>   

Can't you just use kboot?

Use a kernel loader to load the kboot module/initrd, include kboot as 
our firmware, then let kboot do the magic to launch the real linux 
kernel from disk.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 19:25       ` Anthony Liguori
@ 2009-11-24 19:27         ` Alexander Graf
  2009-11-24 19:30           ` Anthony Liguori
  0 siblings, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 19:27 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 24.11.2009, at 20:25, Anthony Liguori wrote:

> Alexander Graf wrote:
>> On 24.11.2009, at 19:55, Anthony Liguori wrote:
>> 
>>  
>>> Alexander Graf wrote:
>>>    
>>>> On our S390x Virtio machine we don't have anywhere to display early printks
>>>> on, because we don't know about VGA or serial ports.
>>>> 
>>>> So instead we just forward everything to the virtio console that we created
>>>> anyways.
>>>>       
>>> What is this used for?
>>>    
>> 
>> This is used for console output before virtio is initialized. I didn't invent it - that's the way it's implemented in the s390 kernels today.
>>  
> 
> I don't see any code that calls this function.  Am I missing something obvious?

It gets called from target-s390x/kvm.c using a special hypercall instruction.

Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 19:26       ` Anthony Liguori
@ 2009-11-24 19:29         ` Alexander Graf
  2009-11-24 20:39           ` Mark Williamson
  2009-11-25  9:58         ` Carsten Otte
  1 sibling, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 19:29 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 24.11.2009, at 20:26, Anthony Liguori wrote:

> Alexander Graf wrote:
>> On 24.11.2009, at 19:53, Anthony Liguori wrote:
>> 
>>  
>>> Alexander Graf wrote:
>>>    
>>>> The default bootloader on S390 is zipl. Because we don't emulate normal S390
>>>> hardware we need to write our own parser for the bootloader configuration,
>>>> so we can boot off real hard disks.
>>>> 
>>>> This patch adds a pretty simple implementation of such an interpreter. It only
>>>> supports 512 bytes sector sizes, always boots the default entry and doesn't
>>>> work with reboots yet. But it's better than nothing.
>>>>       
>>> This is a bit unfortunate.  Wouldn't it be better to write a custom version of zipl that ran in the guest?
>>>    
>> 
>> Yeah, I've been struggling quite a bit with this myself. Writing a custom version that runs in the guest means we have to create
>> 
>> 1) extboot
>> 2) input backdoor
>> 
>> Or implement virtio in that custom version. That sounds like a pretty huge project.
>> 
>> So I decided to go for the easy way for now and hopefully migrate to an in-guest version later.
>>  
> 
> Can't you just use kboot?
> 
> Use a kernel loader to load the kboot module/initrd, include kboot as our firmware, then let kboot do the magic to launch the real linux kernel from disk.

Hm, so we'd have to rely on kexec working properly? I've seen how badly that turned out on the PS3. I guess I'd rather write a virtio implementation :-).

Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 19:27         ` Alexander Graf
@ 2009-11-24 19:30           ` Anthony Liguori
  2009-11-24 19:32             ` Alexander Graf
  2009-11-25 10:00             ` Carsten Otte
  0 siblings, 2 replies; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 19:30 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno

Alexander Graf wrote:
> On 24.11.2009, at 20:25, Anthony Liguori wrote:
>
>   
>> Alexander Graf wrote:
>>     
>>> On 24.11.2009, at 19:55, Anthony Liguori wrote:
>>>
>>>  
>>>       
>>>> Alexander Graf wrote:
>>>>    
>>>>         
>>>>> On our S390x Virtio machine we don't have anywhere to display early printks
>>>>> on, because we don't know about VGA or serial ports.
>>>>>
>>>>> So instead we just forward everything to the virtio console that we created
>>>>> anyways.
>>>>>       
>>>>>           
>>>> What is this used for?
>>>>    
>>>>         
>>> This is used for console output before virtio is initialized. I didn't invent it - that's the way it's implemented in the s390 kernels today.
>>>  
>>>       
>> I don't see any code that calls this function.  Am I missing something obvious?
>>     
>
> It gets called from target-s390x/kvm.c using a special hypercall instruction.
>   

Oh, that's bad :-)

That should really be it's own character device.  We don't really have a 
way to connect two character devices like that.  Maybe muxing?

Regards,

Anthony Liguori
> Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 19:30           ` Anthony Liguori
@ 2009-11-24 19:32             ` Alexander Graf
  2009-11-24 19:48               ` Anthony Liguori
  2009-11-25 10:00             ` Carsten Otte
  1 sibling, 1 reply; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 19:32 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 24.11.2009, at 20:30, Anthony Liguori wrote:

> Alexander Graf wrote:
>> On 24.11.2009, at 20:25, Anthony Liguori wrote:
>> 
>>  
>>> Alexander Graf wrote:
>>>    
>>>> On 24.11.2009, at 19:55, Anthony Liguori wrote:
>>>> 
>>>>       
>>>>> Alexander Graf wrote:
>>>>>           
>>>>>> On our S390x Virtio machine we don't have anywhere to display early printks
>>>>>> on, because we don't know about VGA or serial ports.
>>>>>> 
>>>>>> So instead we just forward everything to the virtio console that we created
>>>>>> anyways.
>>>>>>                
>>>>> What is this used for?
>>>>>           
>>>> This is used for console output before virtio is initialized. I didn't invent it - that's the way it's implemented in the s390 kernels today.
>>>>       
>>> I don't see any code that calls this function.  Am I missing something obvious?
>>>    
>> 
>> It gets called from target-s390x/kvm.c using a special hypercall instruction.
>>  
> 
> Oh, that's bad :-)
> 
> That should really be it's own character device.  We don't really have a way to connect two character devices like that.  
> Maybe muxing?

So you want me to implement char muxing and a bootloader within a week? :)

Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 19:32             ` Alexander Graf
@ 2009-11-24 19:48               ` Anthony Liguori
  2009-11-24 19:58                 ` Alexander Graf
  0 siblings, 1 reply; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 19:48 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno

Alexander Graf wrote:
>> Oh, that's bad :-)
>>
>> That should really be it's own character device.  We don't really have a way to connect two character devices like that.  
>> Maybe muxing?
>>     
>
> So you want me to implement char muxing and a bootloader within a week? :)
>   

Char muxing is already there.

Don't know what to do about the bootloader bit.  At this point, I'm 
curious about whether kboot would be a viable solution.

> Alex

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 19:48               ` Anthony Liguori
@ 2009-11-24 19:58                 ` Alexander Graf
  0 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-24 19:58 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 24.11.2009, at 20:48, Anthony Liguori wrote:

> Alexander Graf wrote:
>>> Oh, that's bad :-)
>>> 
>>> That should really be it's own character device.  We don't really have a way to connect two character devices like that.  Maybe muxing?
>>>    
>> 
>> So you want me to implement char muxing and a bootloader within a week? :)
>>  
> 
> Char muxing is already there.

Ah :-). I guess I could also just create a separate console. It's only for early printk anyways.

> Don't know what to do about the bootloader bit.  At this point, I'm curious about whether kboot would be a viable solution.

My opinion would be to leave it as is for now and switch to a real bootloader that runs inside the guest later.

Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 19:29         ` Alexander Graf
@ 2009-11-24 20:39           ` Mark Williamson
  2009-11-24 21:10             ` Anthony Liguori
  0 siblings, 1 reply; 40+ messages in thread
From: Mark Williamson @ 2009-11-24 20:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Aurelien Jarno, Alexander Graf

> > Can't you just use kboot?
> >
> > Use a kernel loader to load the kboot module/initrd, include kboot as our
> > firmware, then let kboot do the magic to launch the real linux kernel
> > from disk.
> 
> Hm, so we'd have to rely on kexec working properly? I've seen how badly
>  that turned out on the PS3. I guess I'd rather write a virtio
>  implementation :-).

Way back in the mists of time (uh, something like that 2004-05) I had some 
discussions with some of the S390 people about using kboot for more flexible 
boot, since it tallied with their interests.  Although at that point I had the 
impression that zipl was restricted to only one boot option anyhow, so if it 
can now choose from a list then maybe they just enhanced what they had.

Anthony, you might remember these discussions?  I don't know if they went 
anywhere with it.

Cheers,
Mark

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 20:39           ` Mark Williamson
@ 2009-11-24 21:10             ` Anthony Liguori
  2009-11-25  8:35               ` Hannes Reinecke
  2009-11-25 10:02               ` Carsten Otte
  0 siblings, 2 replies; 40+ messages in thread
From: Anthony Liguori @ 2009-11-24 21:10 UTC (permalink / raw)
  To: Mark Williamson; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno, Alexander Graf

Hi Mark!

Mark Williamson wrote:
> Way back in the mists of time (uh, something like that 2004-05) I had some 
> discussions with some of the S390 people about using kboot for more flexible 
> boot, since it tallied with their interests.  Although at that point I had the 
> impression that zipl was restricted to only one boot option anyhow, so if it 
> can now choose from a list then maybe they just enhanced what they had.
>
> Anthony, you might remember these discussions?  I don't know if they went 
> anywhere with it.
>   

I do, that's why I brought it up.  AFAICT, there hasn't been a lot of 
progress with kboot.  Carsten or Alex would probably know better if 
anyone is actually using it on s390s.

Regards,

Anthony Liguori

> Cheers,
> Mark
>   

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 21:10             ` Anthony Liguori
@ 2009-11-25  8:35               ` Hannes Reinecke
  2009-11-25  8:38                 ` Alexander Graf
  2009-11-25 10:09                 ` Carsten Otte
  2009-11-25 10:02               ` Carsten Otte
  1 sibling, 2 replies; 40+ messages in thread
From: Hannes Reinecke @ 2009-11-25  8:35 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Carsten Otte, Alexander Graf, qemu-devel, Aurelien Jarno,
	Mark Williamson

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 2225 bytes --]

On Tue, Nov 24, 2009 at 03:10:24PM -0600, Anthony Liguori wrote:
> Hi Mark!
>
> Mark Williamson wrote:
>> Way back in the mists of time (uh, something like that 2004-05) I had some 
>> discussions with some of the S390 people about using kboot for more 
>> flexible boot, since it tallied with their interests.  Although at that 
>> point I had the impression that zipl was restricted to only one boot 
>> option anyhow, so if it can now choose from a list then maybe they just 
>> enhanced what they had.
>>
>> Anthony, you might remember these discussions?  I don't know if they went 
>> anywhere with it.
>>   
>
> I do, that's why I brought it up.  AFAICT, there hasn't been a lot of 
> progress with kboot.  Carsten or Alex would probably know better if anyone 
> is actually using it on s390s.
>
No, not to my knowledge.

There have been some discussion as if kboot would be beneficial here, but
especially for s390 it doesn't make a lot of sense.

kboot is okay for scenarios where you have a _lot_ of modules in the default
kernel, but need only a very small subset to get the system bootstrapped.
Then you can built a kboot kernel with the driver subset for bootstrapping
and have that loading the 'normal' kernel which then loads all remaining
modules.

If you have (like s390) only about 8 driver modules to care about it's
pretty much pointless as the kboot kernel will have the same configuration
than the normal kernel. So you'll end up with loading the same kernel twice.

And won't change the situation here, as you still have to do the initial
bootstrap somehow. And as this should be quite close to the original system
you'll end up having to support zipl anyway.

So back to the zipl question, it might be an idea to support initially
the SCSI disk layout only. This has the advantage of being far simpler
as the DASD disk layout and should be pretty straightforward to handle.

But that's me talking with no real knowledge of qemu bootstrap internals.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-25  8:35               ` Hannes Reinecke
@ 2009-11-25  8:38                 ` Alexander Graf
  2009-11-25 10:09                 ` Carsten Otte
  1 sibling, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-25  8:38 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: Carsten Otte, Aurelien Jarno, qemu-devel, Mark Williamson


On 25.11.2009, at 09:35, Hannes Reinecke wrote:

> On Tue, Nov 24, 2009 at 03:10:24PM -0600, Anthony Liguori wrote:
>> Hi Mark!
>> 
>> Mark Williamson wrote:
>>> Way back in the mists of time (uh, something like that 2004-05) I had some 
>>> discussions with some of the S390 people about using kboot for more 
>>> flexible boot, since it tallied with their interests.  Although at that 
>>> point I had the impression that zipl was restricted to only one boot 
>>> option anyhow, so if it can now choose from a list then maybe they just 
>>> enhanced what they had.
>>> 
>>> Anthony, you might remember these discussions?  I don't know if they went 
>>> anywhere with it.
>>> 
>> 
>> I do, that's why I brought it up.  AFAICT, there hasn't been a lot of 
>> progress with kboot.  Carsten or Alex would probably know better if anyone 
>> is actually using it on s390s.
>> 
> No, not to my knowledge.
> 
> There have been some discussion as if kboot would be beneficial here, but
> especially for s390 it doesn't make a lot of sense.

Thanks for clarifying this!

> kboot is okay for scenarios where you have a _lot_ of modules in the default
> kernel, but need only a very small subset to get the system bootstrapped.
> Then you can built a kboot kernel with the driver subset for bootstrapping
> and have that loading the 'normal' kernel which then loads all remaining
> modules.
> 
> If you have (like s390) only about 8 driver modules to care about it's
> pretty much pointless as the kboot kernel will have the same configuration
> than the normal kernel. So you'll end up with loading the same kernel twice.
> 
> And won't change the situation here, as you still have to do the initial
> bootstrap somehow. And as this should be quite close to the original system
> you'll end up having to support zipl anyway.

Yes, you'd basically end up writing a zipl interpreter inside the initrd of kboot. Bleks.

> So back to the zipl question, it might be an idea to support initially
> the SCSI disk layout only. This has the advantage of being far simpler
> as the DASD disk layout and should be pretty straightforward to handle.

That's exactly what my zipl patch does. DASD has 4k sector sizes, so DASD layouts are not supported. Fortunately virtio in qemu only exports 512 bytes sector sizes for now, so when you install the VM onto virtio, you're good.

Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 18:53   ` Anthony Liguori
  2009-11-24 18:56     ` Alexander Graf
@ 2009-11-25  8:59     ` Carsten Otte
  1 sibling, 0 replies; 40+ messages in thread
From: Carsten Otte @ 2009-11-25  8:59 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, Alexander Graf, Aurelien Jarno, qemu-devel

Anthony Liguori wrote:
> This is a bit unfortunate.  Wouldn't it be better to write a custom 
> version of zipl that ran in the guest?
> 
> This is like implementing grub in qemu (or pygrub in Xen).  The level of 
> security exposure this introduces is really scary.
Oh that's really the wrong way to see it. We don't have bios, and 
therefore we need _some_ functionality to start up initial code on the 
disk. The interface that Alex is implementing is also used by the real 
hardware to load from disk in case a scsi/fcp volume is used, and it is 
part of the published machine architecture. That's very unlike grub.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 18:55   ` Anthony Liguori
  2009-11-24 18:56     ` Alexander Graf
@ 2009-11-25  9:03     ` Carsten Otte
  1 sibling, 0 replies; 40+ messages in thread
From: Carsten Otte @ 2009-11-25  9:03 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, Alexander Graf, Aurelien Jarno, qemu-devel

Anthony Liguori wrote:
> What is this used for?
On x86 the kernel uses bios output for early prints. We don't have bios 
and do therefore need to bring up a console device as early as possible 
so that we can see kernel panics during I/O subsystem detection/startup. 
All s390 console devices do support this function (3215/3270 and ASCII 
console), and it is used only up to the point when the kernel has its 
console subsystem ready to run.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 19:26       ` Anthony Liguori
  2009-11-24 19:29         ` Alexander Graf
@ 2009-11-25  9:58         ` Carsten Otte
  1 sibling, 0 replies; 40+ messages in thread
From: Carsten Otte @ 2009-11-25  9:58 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, Alexander Graf, Aurelien Jarno, qemu-devel

Anthony Liguori wrote:
> Can't you just use kboot?
> 
> Use a kernel loader to load the kboot module/initrd, include kboot as 
> our firmware, then let kboot do the magic to launch the real linux 
> kernel from disk.
Hehe, and how would you load that initial kernel if you don't have bios?
No matter what, you do need a form of initial loading. And doing it the 
architected way is just plain right.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-24 19:30           ` Anthony Liguori
  2009-11-24 19:32             ` Alexander Graf
@ 2009-11-25 10:00             ` Carsten Otte
  2009-11-25 13:14               ` Arnd Bergmann
  1 sibling, 1 reply; 40+ messages in thread
From: Carsten Otte @ 2009-11-25 10:00 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Carsten Otte, Alexander Graf, Aurelien Jarno, qemu-devel

Anthony Liguori wrote:
> Oh, that's bad :-)
> 
> That should really be it's own character device.  We don't really have a 
> way to connect two character devices like that.  Maybe muxing?
It will be a character device, once the device tree is initialized. 
Better ideas are welcome, just keep in mind basic things like kmalloc 
don't work yet.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-24 21:10             ` Anthony Liguori
  2009-11-25  8:35               ` Hannes Reinecke
@ 2009-11-25 10:02               ` Carsten Otte
  1 sibling, 0 replies; 40+ messages in thread
From: Carsten Otte @ 2009-11-25 10:02 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Alexander Graf, Carsten Otte, qemu-devel, Aurelien Jarno,
	Mark Williamson

Anthony Liguori wrote:
> I do, that's why I brought it up.  AFAICT, there hasn't been a lot of 
> progress with kboot.  Carsten or Alex would probably know better if 
> anyone is actually using it on s390s.
I fail to see how kboot would solve this problem.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter
  2009-11-25  8:35               ` Hannes Reinecke
  2009-11-25  8:38                 ` Alexander Graf
@ 2009-11-25 10:09                 ` Carsten Otte
  1 sibling, 0 replies; 40+ messages in thread
From: Carsten Otte @ 2009-11-25 10:09 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Carsten Otte, Alexander Graf, qemu-devel, Mark Williamson,
	Aurelien Jarno

Hannes Reinecke wrote:
> So back to the zipl question, it might be an idea to support initially
> the SCSI disk layout only. This has the advantage of being far simpler
> as the DASD disk layout and should be pretty straightforward to handle.
Issue is, the dasd disk layout is made for dasds. For eckd, the boot 
code assumes variable blocksize, and the loader uses channel programs. 
For both eckd and fba volumes, it assumes IBM disklabels and FICON 
channel programs. Virt-IO disks do have an msdos-style partition table 
as opposed to this.
That said, you'd need proper virtualiztion of a ficon dasd so that the 
guest could possibly run the dasd boot code. Virt-IO disks otoh are 
fixed block, have an msdos-style partition table, no channel programs, 
and thus look just like scsi disks with a different interface. 
Therefore, I think scsi boot is right for virt-IO disks. And zipl does 
already create this layout in the version found in Sles11 and FC12.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation
  2009-11-24 17:29 ` [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation Alexander Graf
@ 2009-11-25 11:46   ` Paul Brook
  2009-11-25 11:47     ` Alexander Graf
  0 siblings, 1 reply; 40+ messages in thread
From: Paul Brook @ 2009-11-25 11:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Alexander Graf, Aurelien Jarno

> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -30,8 +30,7 @@
> 
>  #include "softfloat.h"
> 
> -#define NB_MMU_MODES 2 // guess
> -#define MMU_USER_IDX 0 // guess
> +#define NB_MMU_MODES 2

The fact that you're modifying a file you added earlier in the same patch 
series gives me very little confidence...

Paul

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation
  2009-11-25 11:46   ` Paul Brook
@ 2009-11-25 11:47     ` Alexander Graf
  0 siblings, 0 replies; 40+ messages in thread
From: Alexander Graf @ 2009-11-25 11:47 UTC (permalink / raw)
  To: Paul Brook; +Cc: Carsten Otte, qemu-devel, Aurelien Jarno


On 25.11.2009, at 12:46, Paul Brook wrote:

>> --- a/target-s390x/cpu.h
>> +++ b/target-s390x/cpu.h
>> @@ -30,8 +30,7 @@
>> 
>> #include "softfloat.h"
>> 
>> -#define NB_MMU_MODES 2 // guess
>> -#define MMU_USER_IDX 0 // guess
>> +#define NB_MMU_MODES 2
> 
> The fact that you're modifying a file you added earlier in the same patch 
> series gives me very little confidence...

I tried to keep the later patches as close to what they were in previous version as possible.
If you like I can merge the changes, but I figured this makes is easier for review.


Alex

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-25 10:00             ` Carsten Otte
@ 2009-11-25 13:14               ` Arnd Bergmann
  2009-11-25 13:47                 ` Carsten Otte
  0 siblings, 1 reply; 40+ messages in thread
From: Arnd Bergmann @ 2009-11-25 13:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Carsten Otte, Carsten Otte, Aurelien Jarno, Alexander Graf

On Wednesday 25 November 2009, Carsten Otte wrote:
> Anthony Liguori wrote:
> > Oh, that's bad :-)
> > 
> > That should really be it's own character device.  We don't really have a 
> > way to connect two character devices like that.  Maybe muxing?
> It will be a character device, once the device tree is initialized. 
> Better ideas are welcome, just keep in mind basic things like kmalloc 
> don't work yet.
> 

Can't you just leave it out for this release? Early printk is great
for debugging, but not essential if you just want to run a guest
as long as you get it past the virtio init phase.

	Arnd <><

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console
  2009-11-25 13:14               ` Arnd Bergmann
@ 2009-11-25 13:47                 ` Carsten Otte
  0 siblings, 0 replies; 40+ messages in thread
From: Carsten Otte @ 2009-11-25 13:47 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Carsten Otte, Aurelien Jarno, qemu-devel, Alexander Graf

Arnd Bergmann wrote:
> Can't you just leave it out for this release? Early printk is great
> for debugging, but not essential if you just want to run a guest
> as long as you get it past the virtio init phase.
The upstream kernel assumes to have this hypercall available when 
running on kvm. You won't get past the virtio init phase if you leave it 
out for kernels <= 2.6.32.

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2009-11-25 13:46 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-24 17:29 [Qemu-devel] [PATCH 00/13] S390x KVM support v4 Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 01/13] S/390 CPU fake emulation Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 02/13] S/390 host/target build system support Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 03/13] S/390 fake TCG implementation Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 04/13] Add KVM support for S390x Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 05/13] Allocate physical memory in low virtual address space Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 06/13] Add support for S390x system emulation Alexander Graf
2009-11-25 11:46   ` Paul Brook
2009-11-25 11:47     ` Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 07/13] Add S390x virtio machine bus Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 08/13] Add S390x virtio machine description Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 09/13] S390 GDB stub Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 10/13] Implement early printk in virtio-console Alexander Graf
2009-11-24 18:55   ` Anthony Liguori
2009-11-24 18:56     ` Alexander Graf
2009-11-24 19:25       ` Anthony Liguori
2009-11-24 19:27         ` Alexander Graf
2009-11-24 19:30           ` Anthony Liguori
2009-11-24 19:32             ` Alexander Graf
2009-11-24 19:48               ` Anthony Liguori
2009-11-24 19:58                 ` Alexander Graf
2009-11-25 10:00             ` Carsten Otte
2009-11-25 13:14               ` Arnd Bergmann
2009-11-25 13:47                 ` Carsten Otte
2009-11-25  9:03     ` Carsten Otte
2009-11-24 17:29 ` [Qemu-devel] [PATCH 11/13] Set default console to virtio on S390x Alexander Graf
2009-11-24 17:29 ` [Qemu-devel] [PATCH 12/13] Add zipl bootloader interpreter Alexander Graf
2009-11-24 18:53   ` Anthony Liguori
2009-11-24 18:56     ` Alexander Graf
2009-11-24 19:26       ` Anthony Liguori
2009-11-24 19:29         ` Alexander Graf
2009-11-24 20:39           ` Mark Williamson
2009-11-24 21:10             ` Anthony Liguori
2009-11-25  8:35               ` Hannes Reinecke
2009-11-25  8:38                 ` Alexander Graf
2009-11-25 10:09                 ` Carsten Otte
2009-11-25 10:02               ` Carsten Otte
2009-11-25  9:58         ` Carsten Otte
2009-11-25  8:59     ` Carsten Otte
2009-11-24 17:29 ` [Qemu-devel] [PATCH 13/13] Add S390 maintainer information Alexander Graf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.