Subject: [PATCH/RFC 3/5] s390 zlive diagnose functions

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

This patch contains everything related to our diagnose instruction
o infrastructure for handling diagnose codes
o handlers for basic diagnoses, which are necessary to run Linux
o additional diagnose codes, which improve guest/host collaboration

Diagnoses are similar to vmmcall/vmcall. There are several calls, which are
defined in our architecture. For these calls, we use the existing ABI. 
Others diagnoses should be changed to fit with the hypercall api.

Signed-off-by: Carsten Otte <[EMAIL PROTECTED]>
---
 diag/Makefile                    |   26 +++++++++++++++++++
 diag/determine_vm_storage_size.c |   29 ++++++++++++++++++++++
 diag/diag.c                      |   51 +++++++++++++++++++++++++++++++++++++++
 diag/ipl_functions.c             |   50 ++++++++++++++++++++++++++++++++++++++
 diag/release_pages.c             |   50 ++++++++++++++++++++++++++++++++++++++
 diag/time_slice_end.c            |   25 +++++++++++++++++++
 include/zldiag.h                 |   50 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 281 insertions(+)

Index: zlive/diag/Makefile
===================================================================
--- /dev/null
+++ zlive/diag/Makefile
@@ -0,0 +1,26 @@
+# z/Live diag makefile
+# Copyright IBM Corp. 2007
+# Author: Carsten Otte <[EMAIL PROTECTED]>
+# This file is licensed under the terms of the GNU General Public License(GPL)
+
+
+%.o : %.c ; echo "     Compiling       " $<; $(CC) $(CFLAGS) -c $<
+
+OBJS := determine_vm_storage_size.o diag.o diag_autoinit.o ipl_functions.o 
time_slice_end.o release_pages.o
+
+all: $(OBJS)
+clean:
+       rm -f $(OBJS) diag_autoinit.c
+
+diag_autoinit.c: determine_vm_storage_size.c ipl_functions.c time_slice_end.c 
release_pages.c
+       echo "  Creating        " $@
+       echo "//Makefile generated" >$@
+       echo "#define __ZLAUTOINIT(f) void f(void);" >>$@
+       cat $^ |grep __ZLAUTOINIT >>$@
+       echo "#undef __ZLAUTOINIT" >>$@
+       echo "#define __ZLAUTOINIT(f) { f(); };" >>$@
+       echo "void autoinit_diag(void) {" >>$@
+       cat $^ |grep __ZLAUTOINIT >>$@
+       echo "}" >>$@
+
+.PHONY: clean all
Index: zlive/diag/determine_vm_storage_size.c
===================================================================
--- /dev/null
+++ zlive/diag/determine_vm_storage_size.c
@@ -0,0 +1,29 @@
+/*
+ * z/Live determine vm storage size diagnose interception
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zldiag.h>
+#include <zlcpu.h>
+#include <zlglobals.h>
+
+static int diag_vm_storage_size(struct zlcpu *cpu)
+{
+       unsigned long size;
+       unsigned int reg;
+       size = glo_memsize;
+       reg = (cl_get_ipbh0(cpu) >> 20) & 0xf;
+       cpu->gpr->regs[reg] = size;
+       return may_do_cpu_work(cpu);
+}
+
+void diag_vm_storage_size_init(void)
+{
+       register_diagnose_handler (DIAG_VM_STORAGE_SIZE, diag_vm_storage_size);
+}
+
+__ZLAUTOINIT(diag_vm_storage_size_init)
Index: zlive/diag/diag.c
===================================================================
--- /dev/null
+++ zlive/diag/diag.c
@@ -0,0 +1,51 @@
+/*
+ * z/Live diagnose interceptions
+ * Copyright IBM Corp. 2007
+ * Authors: Carsten Otte <[EMAIL PROTECTED]>
+ *          Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <string.h>
+
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+#include <zlintercept.h>
+#include <zlinstruction.h>
+#include <zldiag.h>
+#include <zlmessage.h>
+#include <zlautoinit.h>
+
+static intercept_handler_t diag_handlers[MAXIMUM_DIAG_NUMBER+1];
+
+
+int handle_diag(struct zlcpu *cpu)
+{
+       int code = cl_get_ipbh0(cpu) & 0xfff;
+
+       if ((code <= MAXIMUM_DIAG_NUMBER) && (diag_handlers[code])) {
+               return diag_handlers[code](cpu);
+       }
+       log ("cpu %d: unknown diagnose %x at addr %lx, sending prog 1",
+            cpu->cpuno, code, cl_get_psw(cpu).addr);
+       return enter_pgmcheck (cpu, 0x0001);
+}
+
+void register_diagnose_handler(unsigned short code, intercept_handler_t 
handler)
+{
+       if (code > MAXIMUM_DIAG_NUMBER)
+               report_it("diag number to be registered is out of range");
+       if (diag_handlers[code]) {
+               log("aborting: diagnose handler for code %d registered twice", 
code);
+               report_it("diag handler registered twice");
+       }
+       diag_handlers[code] = handler;
+}
+
+void init_diag(void)
+{
+       memset (diag_handlers, 0, 
MAXIMUM_DIAG_NUMBER*sizeof(intercept_handler_t));
+       autoinit_diag(); // see makefile magic
+       register_instruction_handler(OPCODE_MAJOR_DIAG, handle_diag);
+}
Index: zlive/diag/ipl_functions.c
===================================================================
--- /dev/null
+++ zlive/diag/ipl_functions.c
@@ -0,0 +1,50 @@
+/*
+ * z/Live ipl functions diagnose interception
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zldiag.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+#include <zlglobals.h>
+#include <zlimage.h>
+#include <zlreset.h>
+
+int diag_ipl_functions(struct zlcpu *cpu)
+{
+       psw_t new_psw;
+       unsigned int reg;
+       unsigned long subcode;
+       reg = (cl_get_ipa(cpu)) & 0xf;
+       debug ("register is %d", reg);
+       subcode = cpu->gpr->regs[reg] & 0xffff;
+       switch (subcode) {
+       case 3:
+               reset_all();
+       case 4:
+               debug("cpu %d: performing reload ipl", cpu->cpuno);
+               load_ipl();
+               log("cpu %d: reboot in progress, launching new kernel",
+                   cpu->cpuno);
+               new_psw.mask = 0x0000000180000000UL;
+               new_psw.addr = KERN_IMAGE_START;
+               cl_set_psw(cpu, new_psw);
+               return 0;
+       default:
+               debug ("cpu %d: unrecognized subcode of diag 0x308: %ld,"
+                      " sending prog 1",
+                      cpu->cpuno, subcode);
+               return enter_pgmcheck(cpu, 1);
+       }
+}
+
+void diag_ipl_functions_init(void)
+{
+       register_diagnose_handler (DIAG_IPL_FUNCTIONS, diag_ipl_functions);
+}
+
+__ZLAUTOINIT(diag_ipl_functions_init)
Index: zlive/diag/release_pages.c
===================================================================
--- /dev/null
+++ zlive/diag/release_pages.c
@@ -0,0 +1,50 @@
+/*
+ * z/Live release pages diagnose interception
+ * Copyright IBM Corp. 2007
+ * Author: Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zldiag.h>
+#include <zlcpu.h>
+#include <zlcpustat.h>
+#include <sys/mman.h>
+
+static int diag_release_pages(struct zlcpu *cpu)
+{
+       unsigned int regx, regy;
+       uint64_t addrx, addry;
+
+       regx =(cl_get_ipa1(cpu) & 0xf0) >> 4;
+       regy = cl_get_ipa1(cpu) & 0x0f;
+
+       addrx = apply_prefixing(cpu, cpu->gpr->regs[regx]);
+       addry = apply_prefixing(cpu, cpu->gpr->regs[regy]);
+
+       check_addr(cpu, addrx);
+       check_addr(cpu, addry);
+       if ((addrx % 4096) || (addry % 4096) || (addry < addrx))
+               return enter_pgmcheck(cpu, 0x0006);
+
+       debug("diag 10: freeing memory from %lx to %lx\n", cpu->gpr->regs[regx],
+                                       cpu->gpr->regs[regy]+4095);
+       addrx+=glo_origin;
+       addry+=glo_origin;
+       if (madvise((void *)addrx, addry-addrx+4096, MADV_DONTNEED)) {
+               if (errno == ENOMEM) {
+                       log("attempt to free nonmapped memory");
+                       return enter_pgmcheck(cpu, 0x0005);
+               } else
+                       log("madvise failed with errno %d\n", errno);
+       }
+       return may_do_cpu_work(cpu);
+}
+
+void diag_release_pages_init(void)
+{
+       register_diagnose_handler(DIAG_RELEASE_PAGES, diag_release_pages);
+}
+
+__ZLAUTOINIT(diag_release_pages_init)
Index: zlive/diag/time_slice_end.c
===================================================================
--- /dev/null
+++ zlive/diag/time_slice_end.c
@@ -0,0 +1,25 @@
+/*
+ * z/Live time slice end diagnose interception
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zldiag.h>
+#include <zlcpu.h>
+#include <zlcpustat.h>
+
+static int diag_time_slice_end(struct zlcpu *cpu)
+{
+       sched_yield();
+       return may_do_cpu_work(cpu);
+}
+
+void diag_time_slice_end_init(void)
+{
+       register_diagnose_handler (DIAG_TIME_SLICE_END, diag_time_slice_end);
+}
+
+__ZLAUTOINIT(diag_time_slice_end_init)
Index: zlive/include/zldiag.h
===================================================================
--- /dev/null
+++ zlive/include/zldiag.h
@@ -0,0 +1,50 @@
+/*
+ * z/Live diagnose handling header file
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *         Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#ifndef __ZLDIAG_H
+#define __ZLDIAG_H
+#include <zlintercept.h>
+
+//these diagnoses are supported FIXME: we want hypercalls
+#define DIAG_SYNC_READ          0x01 // zlconsole device driver
+#define DIAG_SYNC_WRITE         0x02 // zlconsole device driver
+#define DIAG_ZLDISK_DISK_INFO   0x05 // zldisk device driver
+#define DIAG_ZLDISK_OPEN        0x07 // zldisk device driver
+#define DIAG_ZLDISK_CLOSE       0x09 // zldisk device driver
+#define DIAG_ZLDISK_AIO_SETUP   0x0a // zldisk device driver
+#define DIAG_ZLDISK_SUBMIT_REQ  0x0b // zldisk device driver
+#define DIAG_ZLDISK_GETEVENTS   0x0d // zldisk device driver
+#define DIAG_ZLDISK_IOCTL       0x1d // zldisk device driver
+#define DIAG_ZLICK_INFO                0x0e // zlick device driver
+#define DIAG_ZLICK_OPEN                0x0f // zlick device driver
+#define DIAG_ZLICK_SEND_IRQ     0x11 // zlick device driver
+#define DIAG_ZLDISK_AIO_DESTROY 0x12 // zldisk device driver
+#define DIAG_ZLICK_RELEASE      0x13 // zlick device driver
+#define DIAG_ZESAM_IS_READABLE  0x15 // zesam device driver
+#define DIAG_ZESAM_IS_WRITABLE  0x16 // zesam device driver
+#define DIAG_ZESAM_GET_SIZE     0x17 // zesam device driver
+#define DIAG_ZESAM_MAP          0x19 // zesam device driver
+#define DIAG_ZESAM_UNMAP        0x1a // zesam device driver
+#define DIAG_ZESAM_SYNC         0x1b // zesam device driver
+#define DIAG_ZLDEV_HOTPLUG      0x1e // zldev
+#define DIAG_ZLICK_IP           0x1f // zlick device driver
+#define DIAG_RELEASE_PAGES      0x10
+#define DIAG_PARMLIB_OPEN       0x21
+#define DIAG_PARMLIB_READ       0x22
+#define DIAG_PARMLIB_CLOSE      0x23
+#define DIAG_TIME_SLICE_END     0x44
+#define DIAG_VM_STORAGE_SIZE    0x60
+#define DIAG_IPL_FUNCTIONS      0x308
+
+#define MAXIMUM_DIAG_NUMBER     0x3ff
+
+void register_diagnose_handler (unsigned short code, intercept_handler_t 
handler);
+void init_diag ();
+
+#endif



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to