* [Qemu-devel] s390 host support
@ 2007-11-10 20:42 Bastian Blank
2007-11-12 17:14 ` Ulrich Hecht
2007-11-16 19:09 ` [Qemu-devel] " Bastian Blank
0 siblings, 2 replies; 6+ messages in thread
From: Bastian Blank @ 2007-11-10 20:42 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1.1: Type: text/plain, Size: 1256 bytes --]
Hi folks
Thimo Seufer asked me to check if the s390 host supports works at all.
It did not even build, dyngen failed. I digged into the problem and
found the following:
gcc for s390 generates a data table after each function if necessary
instead of immediate loads. (g5, the oldest supported processor only
suports one halfword immediate load.) dyngen is not prepared for that
and fails. I found that gcc moves this data into the .rodata section if
generating code for z900 and above, which looked like a possible way to
support this.
The attached patch makes qemu build on a s390 host and able to run i386
kernels and userspace. powerpc did not boot, mips failed to start new
processes, the process reports illegal instruction, but the qemu log
does not reflect this.
It does the following changes:
- Hardcode -march=z900 to generate usable op code.
- Add redirection for parameter expansion in op code.
- Cleanup GOTO_LABEL_PARAM.
- Accept any return from function (like "br %r5").
- Support R_390_PC32DBL relocation, including relocations into sections.
- Disable special GOTO_TB handler, it segfaults.
Bastian
--
Each kiss is as the first.
-- Miramanee, Kirk's wife, "The Paradise Syndrome",
stardate 4842.6
[-- Attachment #1.2: diff --]
[-- Type: text/plain, Size: 6061 bytes --]
? diff
? host-op.h
? img
? trace
Index: check_ops.sh
===================================================================
RCS file: /sources/qemu/qemu/check_ops.sh,v
retrieving revision 1.1
diff -u -r1.1 check_ops.sh
--- check_ops.sh 7 Jan 2007 19:38:08 -0000 1.1
+++ check_ops.sh 10 Nov 2007 20:23:52 -0000
@@ -35,6 +35,9 @@
mips*)
ret='\tjr.*ra'
;;
+ s390*)
+ ret='\tbr.*'
+ ;;
*)
echo "Unknown machine `uname -m`"
;;
Index: configure
===================================================================
RCS file: /sources/qemu/qemu/configure,v
retrieving revision 1.169
diff -u -r1.169 configure
--- configure 8 Nov 2007 18:05:36 -0000 1.169
+++ configure 10 Nov 2007 20:23:53 -0000
@@ -341,6 +341,9 @@
ARCH_LDFLAGS="${SP_LDFLAGS}"
fi
;;
+ s390)
+ ARCH_CFLAGS="-march=z900"
+ ;;
esac
if [ "$solaris" = "yes" -a "$cpu" = "x86_64" ] ; then
Index: dyngen-exec.h
===================================================================
RCS file: /sources/qemu/qemu/dyngen-exec.h,v
retrieving revision 1.38
diff -u -r1.38 dyngen-exec.h
--- dyngen-exec.h 16 Sep 2007 21:07:49 -0000 1.38
+++ dyngen-exec.h 10 Nov 2007 20:23:53 -0000
@@ -38,7 +38,7 @@
// Linux/Sparc64 defines uint64_t
#if !(defined (__sparc_v9__) && defined(__linux__))
/* XXX may be done for all 64 bits targets ? */
-#if defined (__x86_64__) || defined(__ia64)
+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
typedef unsigned long uint64_t;
#else
typedef unsigned long long uint64_t;
@@ -55,7 +55,7 @@
typedef signed int int32_t;
// Linux/Sparc64 defines int64_t
#if !(defined (__sparc_v9__) && defined(__linux__))
-#if defined (__x86_64__) || defined(__ia64)
+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
typedef signed long int64_t;
#else
typedef signed long long int64_t;
@@ -205,7 +205,7 @@
#define stringify(s) tostring(s)
#define tostring(s) #s
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__s390__)
/* the symbols are considered non exported so a br immediate is generated */
#define __hidden __attribute__((visibility("hidden")))
#else
@@ -224,6 +224,13 @@
#define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
#define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
#define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
+#elif defined(__s390__)
+extern int __op_param1 __hidden;
+extern int __op_param2 __hidden;
+extern int __op_param3 __hidden;
+#define PARAM1 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param1) "; larl %0,-4; l %0,0(%0)" : "=r"(_r) : ); _r; })
+#define PARAM2 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param2) "; larl %0,-4; l %0,0(%0)" : "=r"(_r) : ); _r; })
+#define PARAM3 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param3) "; larl %0,-4; l %0,0(%0)" : "=r"(_r) : ); _r; })
#else
#if defined(__APPLE__)
static int __op_param1, __op_param2, __op_param3;
@@ -254,7 +261,7 @@
#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
#elif defined(__s390__)
#define EXIT_TB() asm volatile ("br %r14")
-#define GOTO_LABEL_PARAM(n) asm volatile ("bras %r7,8; .long " ASM_NAME(__op_gen_label) #n "; l %r7, 0(%r7); br %r7")
+#define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; .long " ASM_NAME(__op_gen_label) #n)
#elif defined(__alpha__)
#define EXIT_TB() asm volatile ("ret")
#elif defined(__ia64__)
Index: dyngen.c
===================================================================
RCS file: /sources/qemu/qemu/dyngen.c,v
retrieving revision 1.57
diff -u -r1.57 dyngen.c
--- dyngen.c 7 Nov 2007 16:07:32 -0000 1.57
+++ dyngen.c 10 Nov 2007 20:23:53 -0000
@@ -1495,8 +1495,8 @@
p = (void *)(p_end - 2);
if (p == p_start)
error("empty code for %s", name);
- if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)
- error("br %%r14 expected at the end of %s", name);
+ if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)
+ error("br expected at the end of %s", name);
copy_size = p - p_start;
}
#elif defined(HOST_ALPHA)
@@ -2120,6 +2120,19 @@
fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, relname, addend);
break;
+ case R_390_PC32DBL:
+ if (ELF32_ST_TYPE(symtab[ELFW(R_SYM)(rel->r_info)].st_info) == STT_SECTION) {
+ fprintf(outfile,
+ " *(uint32_t *)(gen_code_ptr + %d) += "
+ "((long)&%s - (long)gen_code_ptr) >> 1;\n",
+ reloc_offset, name);
+ }
+ else
+ fprintf(outfile,
+ " *(uint32_t *)(gen_code_ptr + %d) = "
+ "(%s + %d - ((uint32_t)gen_code_ptr + %d)) >> 1;\n",
+ reloc_offset, relname, addend, reloc_offset);
+ break;
default:
error("unsupported s390 relocation (%d)", type);
}
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.70
diff -u -r1.70 exec-all.h
--- exec-all.h 4 Nov 2007 02:24:57 -0000 1.70
+++ exec-all.h 10 Nov 2007 20:23:53 -0000
@@ -350,7 +350,8 @@
"1:\n");\
} while (0)
-#elif defined(__s390__)
+#elif 0 && defined(__s390__)
+/* XXX: SIGSEGV */
/* GCC spills R13, so we have to restore it before branching away */
#define GOTO_TB(opname, tbparam, n)\
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] s390 host support
2007-11-10 20:42 [Qemu-devel] s390 host support Bastian Blank
@ 2007-11-12 17:14 ` Ulrich Hecht
2007-11-13 13:00 ` Bastian Blank
2007-11-16 19:09 ` [Qemu-devel] " Bastian Blank
1 sibling, 1 reply; 6+ messages in thread
From: Ulrich Hecht @ 2007-11-12 17:14 UTC (permalink / raw)
To: qemu-devel
On Saturday 10 November 2007, Bastian Blank wrote:
> Thimo Seufer asked me to check if the s390 host supports works at all.
> It did not even build, dyngen failed.
A 31-bit build of the CVS code works fine for me. (At least if I add the
br %rANY fix that is also in your patch and the jcc patch that Thiemo
has not committed yet.)
A 31-bit build using your patch works as well, but it also needs the jcc
patch. The only reason it needs to be compiled with -march=z900 is the
use of larl in the inline assembly code, which can be avoided by simply
omitting it in the PARAMx macros (the bras already writes the address to
the register) and reverting to the code currently in CVS for
GOTO_LABEL_PARAM. (The GOTO_TB hack does not seem to be necessary any
more.)
> I digged into the problem and
> found the following:
> gcc for s390 generates a data table after each function if necessary
> instead of immediate loads.
It actually generates it inline, doing something like
op_something:
bras %r13, 8
.long <some data>
...
In other words, it branches over the data, storing the "return address"
(which is actually a pointer to the data) in r13.
> (g5, the oldest supported processor only
> suports one halfword immediate load.) dyngen is not prepared for that
> and fails.
> I found that gcc moves this data into the .rodata section
> if generating code for z900 and above, which looked like a possible
> way to support this.
(My) GCC only does this when generating 64-bit code.
> - Support R_390_PC32DBL relocation, including relocations into
> sections.
Again, my GCC only generates this relocation when compiling 64-bit code.
With your patch and some obvious fixes (ELFCLASS64, GETPC,
$hostlongbits)) it builds as 64-bit, but it segfaults in the first
translation block.
CU
Uli
--
Heute ist
- Dr. Sun Yat-sens Geburtstag (in Taiwan)
- Gedenktag (in Bermuda, Cayman-Inseln)
- Tag der Veteranen (in den USA (26 Staaten))
- Unabhängigkeit von Cartagena (in Kolumbien)
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] s390 host support
2007-11-12 17:14 ` Ulrich Hecht
@ 2007-11-13 13:00 ` Bastian Blank
2007-11-13 14:05 ` Ulrich Hecht
0 siblings, 1 reply; 6+ messages in thread
From: Bastian Blank @ 2007-11-13 13:00 UTC (permalink / raw)
To: qemu-devel
On Mon, Nov 12, 2007 at 06:14:43PM +0100, Ulrich Hecht wrote:
> On Saturday 10 November 2007, Bastian Blank wrote:
> > Thimo Seufer asked me to check if the s390 host supports works at all.
> > It did not even build, dyngen failed.
> A 31-bit build of the CVS code works fine for me.
Please describe the environment you work in, including compiler versions
and patchsets.
For me it does not work with gcc 3.4, 4.2, 4.3 snapshot from september
with binutils 2.18 from Debian unstable. The gcc includes patches for
multilib support. The testenvironment is a z900 aka 2064.
> A 31-bit build of the CVS code works fine for me. (At least if I add the
> br %rANY fix that is also in your patch and the jcc patch that Thiemo
> has not committed yet.)
The jcc fix looks like a workaround for an undescribed problem. Please
describe this. Hmm, the comments say "for unknown reasons".
> A 31-bit build using your patch works as well, but it also needs the jcc
> patch.
Nope, all my tests worked fine so long.
> The only reason it needs to be compiled with -march=z900 is the
> use of larl in the inline assembly code,
No. -march=z900 changes the generated code.
> > I digged into the problem and
> > found the following:
> > gcc for s390 generates a data table after each function if necessary
> > instead of immediate loads.
> It actually generates it inline, doing something like
> op_something:
> bras %r13, 8
> .long <some data>
> ...
If you use -O0 it sometimes generates this code and the data table in
versions up to 4.2. Using 4.3, I never saw this.
> > - Support R_390_PC32DBL relocation, including relocations into
> > sections.
> Again, my GCC only generates this relocation when compiling 64-bit code.
The GCC does not generate any relocation. Relocations are emited by the
assembler. And binutils 2.18 emits this.
> With your patch and some obvious fixes (ELFCLASS64, GETPC,
> $hostlongbits)) it builds as 64-bit, but it segfaults in the first
> translation block.
I did'n say it will work in 64bit mode.
Bastian
--
The best diplomat I know is a fully activated phaser bank.
-- Scotty
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] s390 host support
2007-11-13 13:00 ` Bastian Blank
@ 2007-11-13 14:05 ` Ulrich Hecht
2007-11-13 17:20 ` Bastian Blank
0 siblings, 1 reply; 6+ messages in thread
From: Ulrich Hecht @ 2007-11-13 14:05 UTC (permalink / raw)
To: qemu-devel
On Tuesday 13 November 2007, Bastian Blank wrote:
> Please describe the environment you work in, including compiler
> versions and patchsets.
gcc 3.3 (Hammer branch, really vintage stuff) with recent (2.18.50)
binutils. We already use gcc 4 for targets where the old one won't work
(ia64 and ppc64); maybe we should do so for s390 as well.
> The jcc fix looks like a workaround for an undescribed problem. Please
> describe this. Hmm, the comments say "for unknown reasons".
I am actually suspecting this to be a compiler bug, but I did not
investigate it further once I found that disabling it helps.
CU
Uli
--
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] s390 host support
2007-11-13 14:05 ` Ulrich Hecht
@ 2007-11-13 17:20 ` Bastian Blank
0 siblings, 0 replies; 6+ messages in thread
From: Bastian Blank @ 2007-11-13 17:20 UTC (permalink / raw)
To: qemu-devel
On Tue, Nov 13, 2007 at 03:05:25PM +0100, Ulrich Hecht wrote:
> gcc 3.3 (Hammer branch, really vintage stuff) with recent (2.18.50)
> binutils.
Okay, ancient compiler with the other binutils branch. I did not use
them since years.
> I am actually suspecting this to be a compiler bug, but I did not
> investigate it further once I found that disabling it helps.
So you use ancient compilers and workaround compiler bugs.
Bastian
--
Women professionals do tend to over-compensate.
-- Dr. Elizabeth Dehaver, "Where No Man Has Gone Before",
stardate 1312.9.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] Re: s390 host support
2007-11-10 20:42 [Qemu-devel] s390 host support Bastian Blank
2007-11-12 17:14 ` Ulrich Hecht
@ 2007-11-16 19:09 ` Bastian Blank
1 sibling, 0 replies; 6+ messages in thread
From: Bastian Blank @ 2007-11-16 19:09 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 544 bytes --]
Updated patch attached.
On Sat, Nov 10, 2007 at 09:42:19PM +0100, Bastian Blank wrote:
> It does the following changes:
> - Hardcode -march=z900 to generate usable op code.
> - Add redirection for parameter expansion in op code.
> - Cleanup GOTO_LABEL_PARAM.
> - Accept any return from function (like "br %r5").
> - Support R_390_PC32DBL relocation, including relocations into sections.
- Remove special GOTO_TB handler, it segfaults.
Bastian
--
A little suffering is good for the soul.
-- Kirk, "The Corbomite Maneuver", stardate 1514.0
[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 6307 bytes --]
Index: check_ops.sh
===================================================================
RCS file: /sources/qemu/qemu/check_ops.sh,v
retrieving revision 1.1
diff -u -r1.1 check_ops.sh
--- check_ops.sh 7 Jan 2007 19:38:08 -0000 1.1
+++ check_ops.sh 16 Nov 2007 19:06:44 -0000
@@ -35,6 +35,9 @@
mips*)
ret='\tjr.*ra'
;;
+ s390*)
+ ret='\tbr.*'
+ ;;
*)
echo "Unknown machine `uname -m`"
;;
Index: configure
===================================================================
RCS file: /sources/qemu/qemu/configure,v
retrieving revision 1.172
diff -u -r1.172 configure
--- configure 12 Nov 2007 01:56:17 -0000 1.172
+++ configure 16 Nov 2007 19:06:44 -0000
@@ -354,6 +354,9 @@
ARCH_LDFLAGS="${SP_LDFLAGS}"
fi
;;
+ s390)
+ ARCH_CFLAGS="-march=z900"
+ ;;
esac
if [ "$solaris" = "yes" -a "$cpu" = "x86_64" ] ; then
Index: dyngen-exec.h
===================================================================
RCS file: /sources/qemu/qemu/dyngen-exec.h,v
retrieving revision 1.38
diff -u -r1.38 dyngen-exec.h
--- dyngen-exec.h 16 Sep 2007 21:07:49 -0000 1.38
+++ dyngen-exec.h 16 Nov 2007 19:06:44 -0000
@@ -38,7 +38,7 @@
// Linux/Sparc64 defines uint64_t
#if !(defined (__sparc_v9__) && defined(__linux__))
/* XXX may be done for all 64 bits targets ? */
-#if defined (__x86_64__) || defined(__ia64)
+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
typedef unsigned long uint64_t;
#else
typedef unsigned long long uint64_t;
@@ -55,7 +55,7 @@
typedef signed int int32_t;
// Linux/Sparc64 defines int64_t
#if !(defined (__sparc_v9__) && defined(__linux__))
-#if defined (__x86_64__) || defined(__ia64)
+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
typedef signed long int64_t;
#else
typedef signed long long int64_t;
@@ -205,7 +205,7 @@
#define stringify(s) tostring(s)
#define tostring(s) #s
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__s390__)
/* the symbols are considered non exported so a br immediate is generated */
#define __hidden __attribute__((visibility("hidden")))
#else
@@ -224,6 +224,13 @@
#define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
#define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
#define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
+#elif defined(__s390__)
+extern int __op_param1 __hidden;
+extern int __op_param2 __hidden;
+extern int __op_param3 __hidden;
+#define PARAM1 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param1) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
+#define PARAM2 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param2) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
+#define PARAM3 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param3) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
#else
#if defined(__APPLE__)
static int __op_param1, __op_param2, __op_param3;
@@ -254,7 +261,7 @@
#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
#elif defined(__s390__)
#define EXIT_TB() asm volatile ("br %r14")
-#define GOTO_LABEL_PARAM(n) asm volatile ("bras %r7,8; .long " ASM_NAME(__op_gen_label) #n "; l %r7, 0(%r7); br %r7")
+#define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; .long " ASM_NAME(__op_gen_label) #n)
#elif defined(__alpha__)
#define EXIT_TB() asm volatile ("ret")
#elif defined(__ia64__)
Index: dyngen.c
===================================================================
RCS file: /sources/qemu/qemu/dyngen.c,v
retrieving revision 1.57
diff -u -r1.57 dyngen.c
--- dyngen.c 7 Nov 2007 16:07:32 -0000 1.57
+++ dyngen.c 16 Nov 2007 19:06:45 -0000
@@ -1495,8 +1495,8 @@
p = (void *)(p_end - 2);
if (p == p_start)
error("empty code for %s", name);
- if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)
- error("br %%r14 expected at the end of %s", name);
+ if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)
+ error("br expected at the end of %s", name);
copy_size = p - p_start;
}
#elif defined(HOST_ALPHA)
@@ -2120,6 +2120,19 @@
fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, relname, addend);
break;
+ case R_390_PC32DBL:
+ if (ELF32_ST_TYPE(symtab[ELFW(R_SYM)(rel->r_info)].st_info) == STT_SECTION) {
+ fprintf(outfile,
+ " *(uint32_t *)(gen_code_ptr + %d) += "
+ "((long)&%s - (long)gen_code_ptr) >> 1;\n",
+ reloc_offset, name);
+ }
+ else
+ fprintf(outfile,
+ " *(uint32_t *)(gen_code_ptr + %d) = "
+ "(%s + %d - ((uint32_t)gen_code_ptr + %d)) >> 1;\n",
+ reloc_offset, relname, addend, reloc_offset);
+ break;
default:
error("unsupported s390 relocation (%d)", type);
}
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.70
diff -u -r1.70 exec-all.h
--- exec-all.h 4 Nov 2007 02:24:57 -0000 1.70
+++ exec-all.h 16 Nov 2007 19:06:45 -0000
@@ -350,24 +350,6 @@
"1:\n");\
} while (0)
-#elif defined(__s390__)
-/* GCC spills R13, so we have to restore it before branching away */
-
-#define GOTO_TB(opname, tbparam, n)\
-do {\
- static void __attribute__((used)) *dummy ## n = &&dummy_label ## n;\
- static void __attribute__((used)) *__op_label ## n \
- __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
- __asm__ __volatile__ ( \
- "l %%r13,52(%%r15)\n" \
- "br %0\n" \
- : : "r" (((TranslationBlock*)tbparam)->tb_next[n]));\
- \
- for(;*((int*)0);); /* just to keep GCC busy */ \
-label ## n: ;\
-dummy_label ## n: ;\
-} while(0)
-
#else
/* jump to next block operations (more portable code, does not need
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-11-16 19:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-10 20:42 [Qemu-devel] s390 host support Bastian Blank
2007-11-12 17:14 ` Ulrich Hecht
2007-11-13 13:00 ` Bastian Blank
2007-11-13 14:05 ` Ulrich Hecht
2007-11-13 17:20 ` Bastian Blank
2007-11-16 19:09 ` [Qemu-devel] " Bastian Blank
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).