Patchwork [15/35] tcg-s390: Query instruction extensions that are installed.

login
register
mail settings
Submitter Richard Henderson
Date June 4, 2010, 7:14 p.m.
Message ID <1275678883-7082-16-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/54680/
State New
Headers show

Comments

Richard Henderson - June 4, 2010, 7:14 p.m.
Verify that we have all the instruction extensions that we generate.
Future patches can tailor code generation to the set of instructions
that are present.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/s390/tcg-target.c |  113 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 113 insertions(+), 0 deletions(-)
Aurelien Jarno - June 10, 2010, 10:28 a.m.
On Fri, Jun 04, 2010 at 12:14:23PM -0700, Richard Henderson wrote:
> Verify that we have all the instruction extensions that we generate.
> Future patches can tailor code generation to the set of instructions
> that are present.
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  tcg/s390/tcg-target.c |  113 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 113 insertions(+), 0 deletions(-)
> 
> diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
> index 3944cb1..d99bb5c 100644
> --- a/tcg/s390/tcg-target.c
> +++ b/tcg/s390/tcg-target.c
> @@ -229,6 +229,17 @@ static void *qemu_st_helpers[4] = {
>  
>  static uint8_t *tb_ret_addr;
>  
> +/* A list of relevant facilities used by this translator.  Some of these
> +   are required for proper operation, and these are checked at startup.  */
> +
> +#define FACILITY_ZARCH		(1ULL << (63 - 1))
> +#define FACILITY_ZARCH_ACTIVE	(1ULL << (63 - 2))
> +#define FACILITY_LONG_DISP	(1ULL << (63 - 18))
> +#define FACILITY_EXT_IMM	(1ULL << (63 - 21))
> +#define FACILITY_GEN_INST_EXT	(1ULL << (63 - 34))
> +
> +static uint64_t facilities;
> +
>  static void patch_reloc(uint8_t *code_ptr, int type,
>                  tcg_target_long value, tcg_target_long addend)
>  {
> @@ -1177,6 +1188,106 @@ static const TCGTargetOpDef s390_op_defs[] = {
>      { -1 },
>  };
>  
> +/* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
> +   this information.  However, getting at that entry is not easy this far
> +   away from main.  Our options are: start searching from environ, but
> +   that fails as soon as someone does a setenv in between.  Read the data
> +   from /proc/self/auxv.  Or do the probing ourselves.  The only thing
> +   extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
> +   that the kernel saves all 64-bits of the registers around traps while
> +   in 31-bit mode.  But this is true of all "recent" kernels (ought to dig
> +   back and see from when this might not be true).  */
> +
> +#include <signal.h>
> +
> +static volatile sig_atomic_t got_sigill;
> +
> +static void sigill_handler(int sig)
> +{
> +    got_sigill = 1;
> +}
> +
> +static void query_facilities(void)
> +{
> +    struct sigaction sa_old, sa_new;
> +    register int r0 __asm__("0");
> +    register void *r1 __asm__("1");
> +    int fail;
> +
> +    memset(&sa_new, 0, sizeof(sa_new));
> +    sa_new.sa_handler = sigill_handler;
> +    sigaction(SIGILL, &sa_new, &sa_old);
> +
> +    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
> +       we need not do any more probing.  Unfortunately, this itself is an
> +       extension and the original STORE FACILITY LIST instruction is
> +       kernel-only, storing its results at absolute address 200.  */
> +    /* stfle 0(%r1) */
> +    r1 = &facilities;
> +    asm volatile(".word 0xb2b0,0x1000"
> +                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");

Wouldn't it be possible to use the instruction directly instead of
dumping the opcode values? Same below

> +
> +    if (got_sigill) {
> +        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
> +           kind of instruction that we're interested in.  */
> +        /* ??? Possibly some of these are in practice never present unless
> +           the store-facility-extended facility is also present.  But since
> +           that isn't documented it's just better to probe for each.  */
> +
> +        /* Test for z/Architecture.  Required even in 31-bit mode.  */
> +        got_sigill = 0;
> +        /* agr %r0,%r0 */
> +        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
> +        if (!got_sigill) {
> +            facilities |= FACILITY_ZARCH | FACILITY_ZARCH_ACTIVE;
> +        }
> +
> +        /* Test for long displacement.  */
> +        got_sigill = 0;
> +        /* ly %r0,0(%r1) */
> +        r1 = &facilities;
> +        asm volatile(".word 0xe300,0x1000,0x0058"
> +                     : "=r"(r0) : "r"(r1) : "cc");
> +        if (!got_sigill) {
> +            facilities |= FACILITY_LONG_DISP;
> +        }
> +
> +        /* Test for extended immediates.  */
> +        got_sigill = 0;
> +        /* afi %r0,0 */
> +        asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
> +        if (!got_sigill) {
> +            facilities |= FACILITY_EXT_IMM;
> +        }
> +
> +        /* Test for general-instructions-extension.  */
> +        got_sigill = 0;
> +        /* msfi %r0,1 */
> +        asm volatile(".word 0xc201,0x0000,0x0001");
> +        if (!got_sigill) {
> +            facilities |= FACILITY_GEN_INST_EXT;
> +        }
> +    }
> +
> +    sigaction(SIGILL, &sa_old, NULL);
> +
> +    /* The translator currently uses these extensions unconditionally.
> +       Pruning this back to the base ESA/390 architecture doesn't seem
> +       worthwhile, since even the KVM target requires z/Arch.  */
> +    fail = 0;
> +    if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
> +        fprintf(stderr, "TCG: z/Arch facility is required\n");
> +        fail = 1;
> +    }
> +    if ((facilities & FACILITY_LONG_DISP) == 0) {
> +        fprintf(stderr, "TCG: long-displacement facility is required\n");
> +        fail = 1;
> +    }
> +    if (fail) {
> +        exit(-1);
> +    }
> +}
> +
>  void tcg_target_init(TCGContext *s)
>  {
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1186,6 +1297,8 @@ void tcg_target_init(TCGContext *s)
>      }
>  #endif
>  
> +    query_facilities();
> +
>      tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
>      tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
>  
> -- 
> 1.7.0.1
> 
> 
>
Richard Henderson - June 10, 2010, 10:19 p.m.
On 06/10/2010 03:28 AM, Aurelien Jarno wrote:
>> +    asm volatile(".word 0xb2b0,0x1000"
>> +                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
> 
> Wouldn't it be possible to use the instruction directly instead of
> dumping the opcode values? Same below

No, they aren't recognized by older assemblers.  For instance, the one shipped
with RHEL 5.5, and possibly even by Debian Lenny (I don't currently have access
to that machine to check). Apparently some of these are quite new insns -- 2008 era.

That said, all the hardware to which either I or agraf have access are the latest
z10 machines.  Frankly I expect that to be true of most if not all machines, since
I think it's just a microcode update which everyone with an active support contract
can get.


r~
Aurelien Jarno - June 11, 2010, 8:06 a.m.
On Thu, Jun 10, 2010 at 03:19:25PM -0700, Richard Henderson wrote:
> On 06/10/2010 03:28 AM, Aurelien Jarno wrote:
> >> +    asm volatile(".word 0xb2b0,0x1000"
> >> +                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
> > 
> > Wouldn't it be possible to use the instruction directly instead of
> > dumping the opcode values? Same below
> 
> No, they aren't recognized by older assemblers.  For instance, the one shipped
> with RHEL 5.5, and possibly even by Debian Lenny (I don't currently have access
> to that machine to check). Apparently some of these are quite new insns -- 2008 era.
> 
> That said, all the hardware to which either I or agraf have access are the latest
> z10 machines.  Frankly I expect that to be true of most if not all machines, since
> I think it's just a microcode update which everyone with an active support contract
> can get.
> 

FYI, that's the /proc/cpuinfo of s390 machines I have (more or less)
access:

features        : esan3 zarch msa ldisp 
features        : esan3 zarch stfle msa ldisp eimm dfp
features        : esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs 

So that's seems fine. However, looking more in details in the code
again, I do wonder about this part:

> +        /* Test for z/Architecture.  Required even in 31-bit mode.  */
> +        got_sigill = 0;
> +        /* agr %r0,%r0 */
> +        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
> +        if (!got_sigill) {
> +            facilities |= FACILITY_ZARCH | FACILITY_ZARCH_ACTIVE;
> +        }
> +

What's the difference between FACILITY_ZARCH and FACILITY_ZARCH_ACTIVE,
as both are actually flagged together. My guess is that
FACILITY_ZARCH_ACTIVE is needed in 64-bit mode, why FACILITY_ZARCH is
only needed for a possible future 32-bit mode. Is it correct?
Richard Henderson - June 11, 2010, 1:07 p.m.
On 06/11/2010 01:06 AM, Aurelien Jarno wrote:
> What's the difference between FACILITY_ZARCH and FACILITY_ZARCH_ACTIVE,
> as both are actually flagged together. My guess is that
> FACILITY_ZARCH_ACTIVE is needed in 64-bit mode, why FACILITY_ZARCH is
> only needed for a possible future 32-bit mode. Is it correct?

Loosely,

ZARCH is set when the system is 64-bit capable, whether or not it is active.
The OS would check this bit at startup if it wanted to change modes.  This
bit isn't really interesting to us in userspace.

ZARCH_ACTIVE is set when the system is in 64-bit mode, i.e. you've booted
with a 64-bit kernel.  Note that this says nothing about the address 
decoding mode -- this bit can be set while the PSW is set for 31-bit
address translation, e.g. running a 32-bit program on a 64-bit kernel.


r~
Richard Henderson - June 11, 2010, 1:13 p.m.
On 06/11/2010 01:06 AM, Aurelien Jarno wrote:
>> That said, all the hardware to which either I or agraf have access are the latest
>> z10 machines.  Frankly I expect that to be true of most if not all machines, since
>> I think it's just a microcode update which everyone with an active support contract
>> can get.
>>
> 
> FYI, that's the /proc/cpuinfo of s390 machines I have (more or less)
> access:
> 
> features        : esan3 zarch msa ldisp 
> features        : esan3 zarch stfle msa ldisp eimm dfp
> features        : esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs 

Interesting that your first one doesn't have stfle.  That one will have to
go through the SIGILL path.  I would be very interested to have you test 
that code path.

Also, what era is that second machine without highgprs?  Is it running an
old kernel, or a 32-bit kernel?


r~
Aurelien Jarno - June 12, 2010, 11:57 a.m.
On Fri, Jun 11, 2010 at 06:07:52AM -0700, Richard Henderson wrote:
> On 06/11/2010 01:06 AM, Aurelien Jarno wrote:
> > What's the difference between FACILITY_ZARCH and FACILITY_ZARCH_ACTIVE,
> > as both are actually flagged together. My guess is that
> > FACILITY_ZARCH_ACTIVE is needed in 64-bit mode, why FACILITY_ZARCH is
> > only needed for a possible future 32-bit mode. Is it correct?
> 
> Loosely,
> 
> ZARCH is set when the system is 64-bit capable, whether or not it is active.
> The OS would check this bit at startup if it wanted to change modes.  This
> bit isn't really interesting to us in userspace.
> 
> ZARCH_ACTIVE is set when the system is in 64-bit mode, i.e. you've booted
> with a 64-bit kernel.  Note that this says nothing about the address 
> decoding mode -- this bit can be set while the PSW is set for 31-bit
> address translation, e.g. running a 32-bit program on a 64-bit kernel.
> 

So in short we never use ZARCH in QEMU, so we probably don't want to
have this #define, nor add it at the same time as FACILITY_ZARCH_ACTIVE.
Aurelien Jarno - June 13, 2010, 10:49 a.m.
On Fri, Jun 11, 2010 at 06:13:49AM -0700, Richard Henderson wrote:
> On 06/11/2010 01:06 AM, Aurelien Jarno wrote:
> >> That said, all the hardware to which either I or agraf have access are the latest
> >> z10 machines.  Frankly I expect that to be true of most if not all machines, since
> >> I think it's just a microcode update which everyone with an active support contract
> >> can get.
> >>
> > 
> > FYI, that's the /proc/cpuinfo of s390 machines I have (more or less)
> > access:
> > 
> > features        : esan3 zarch msa ldisp 
> > features        : esan3 zarch stfle msa ldisp eimm dfp
> > features        : esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs 
> 
> Interesting that your first one doesn't have stfle.  That one will have to
> go through the SIGILL path.  I would be very interested to have you test 
> that code path.

I have tried, it correctly detects zarch and ldisp.

> Also, what era is that second machine without highgprs?  Is it running an
> old kernel, or a 32-bit kernel?
> 

I have very few infos about it, it's an IBM System z10 machine running a
64-bit 2.6.26 kernel.
Richard Henderson - June 13, 2010, 4:02 p.m.
On 06/13/2010 03:49 AM, Aurelien Jarno wrote:
>> Also, what era is that second machine without highgprs?  Is it running an
>> old kernel, or a 32-bit kernel?
> 
> I have very few infos about it, it's an IBM System z10 machine running a
> 64-bit 2.6.26 kernel.

Ah, I see it now: ea2a4d3a3a929ef494952bba57a0ef1a8a877881

    [S390] 64-bit register support for 31-bit processes

which adds a mechanism to pass the high parts of the gprs
in the ucontext to the 31-bit signal handler, and adds a
spot for them in the 31-bit core dump.

It doesn't change the actual saving of registers within
the kernel.  Since we take asynchronous signals and return
from them (as opposed to always longjmping out), we cannot
use the full 64-bit register within a 31-bit process without
having that bit set in HWCAP.

Something to remember if we ever implement TCG for 31-bit mode.
At the moment we only allow KVM in 31-bit mode.


r~
Aurelien Jarno - June 13, 2010, 4:44 p.m.
On Sun, Jun 13, 2010 at 09:02:40AM -0700, Richard Henderson wrote:
> On 06/13/2010 03:49 AM, Aurelien Jarno wrote:
> >> Also, what era is that second machine without highgprs?  Is it running an
> >> old kernel, or a 32-bit kernel?
> > 
> > I have very few infos about it, it's an IBM System z10 machine running a
> > 64-bit 2.6.26 kernel.
> 
> Ah, I see it now: ea2a4d3a3a929ef494952bba57a0ef1a8a877881
> 
>     [S390] 64-bit register support for 31-bit processes
> 
> which adds a mechanism to pass the high parts of the gprs
> in the ucontext to the 31-bit signal handler, and adds a
> spot for them in the 31-bit core dump.
> 
> It doesn't change the actual saving of registers within
> the kernel.  Since we take asynchronous signals and return
> from them (as opposed to always longjmping out), we cannot
> use the full 64-bit register within a 31-bit process without
> having that bit set in HWCAP.
> 
> Something to remember if we ever implement TCG for 31-bit mode.
> At the moment we only allow KVM in 31-bit mode.
> 

Is KVM in 31-bit mode actually functional?
Alexander Graf - June 13, 2010, 10:23 p.m.
On 13.06.2010, at 18:44, Aurelien Jarno wrote:

> On Sun, Jun 13, 2010 at 09:02:40AM -0700, Richard Henderson wrote:
>> On 06/13/2010 03:49 AM, Aurelien Jarno wrote:
>>>> Also, what era is that second machine without highgprs?  Is it running an
>>>> old kernel, or a 32-bit kernel?
>>> 
>>> I have very few infos about it, it's an IBM System z10 machine running a
>>> 64-bit 2.6.26 kernel.
>> 
>> Ah, I see it now: ea2a4d3a3a929ef494952bba57a0ef1a8a877881
>> 
>>    [S390] 64-bit register support for 31-bit processes
>> 
>> which adds a mechanism to pass the high parts of the gprs
>> in the ucontext to the 31-bit signal handler, and adds a
>> spot for them in the 31-bit core dump.
>> 
>> It doesn't change the actual saving of registers within
>> the kernel.  Since we take asynchronous signals and return
>> from them (as opposed to always longjmping out), we cannot
>> use the full 64-bit register within a 31-bit process without
>> having that bit set in HWCAP.
>> 
>> Something to remember if we ever implement TCG for 31-bit mode.
>> At the moment we only allow KVM in 31-bit mode.
>> 
> 
> Is KVM in 31-bit mode actually functional?

I'm not aware of anything preventing it to be. But I honestly haven't tried. As long as all hypercall parameters stay within the first 32/31 bits, things should be safe.

Alex
Richard Henderson - June 14, 2010, 4:20 p.m.
On 06/13/2010 03:23 PM, Alexander Graf wrote:
> On 13.06.2010, at 18:44, Aurelien Jarno wrote:
>> Is KVM in 31-bit mode actually functional?
> 
> I'm not aware of anything preventing it to be. But I honestly haven't
> tried. As long as all hypercall parameters stay within the first
> 32/31 bits, things should be safe.

On the other hand, is there any point in supporting it?
This does seem to be a case for which it does seem like
having the extra VM space (KVM+TCG) and the extra register
size (TCG) is extremely helpful.

I'd be just as happy to adjust the configury to actively
prevent compilation in 31-bit mode, rather than pretend
it might work and never bother to test it...


r~
Alexander Graf - June 14, 2010, 5:39 p.m.
Am 14.06.2010 um 18:20 schrieb Richard Henderson <rth@twiddle.net>:

> On 06/13/2010 03:23 PM, Alexander Graf wrote:
>> On 13.06.2010, at 18:44, Aurelien Jarno wrote:
>>> Is KVM in 31-bit mode actually functional?
>>
>> I'm not aware of anything preventing it to be. But I honestly haven't
>> tried. As long as all hypercall parameters stay within the first
>> 32/31 bits, things should be safe.
>
> On the other hand, is there any point in supporting it?
> This does seem to be a case for which it does seem like
> having the extra VM space (KVM+TCG) and the extra register
> size (TCG) is extremely helpful.
>
> I'd be just as happy to adjust the configury to actively
> prevent compilation in 31-bit mode, rather than pretend
> it might work and never bother to test it...

Yeah, I agree. 31-bit is really deprecated by now anyways. Aurelien  
was the one interested in it.

Alex

>

Patch

diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 3944cb1..d99bb5c 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -229,6 +229,17 @@  static void *qemu_st_helpers[4] = {
 
 static uint8_t *tb_ret_addr;
 
+/* A list of relevant facilities used by this translator.  Some of these
+   are required for proper operation, and these are checked at startup.  */
+
+#define FACILITY_ZARCH		(1ULL << (63 - 1))
+#define FACILITY_ZARCH_ACTIVE	(1ULL << (63 - 2))
+#define FACILITY_LONG_DISP	(1ULL << (63 - 18))
+#define FACILITY_EXT_IMM	(1ULL << (63 - 21))
+#define FACILITY_GEN_INST_EXT	(1ULL << (63 - 34))
+
+static uint64_t facilities;
+
 static void patch_reloc(uint8_t *code_ptr, int type,
                 tcg_target_long value, tcg_target_long addend)
 {
@@ -1177,6 +1188,106 @@  static const TCGTargetOpDef s390_op_defs[] = {
     { -1 },
 };
 
+/* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
+   this information.  However, getting at that entry is not easy this far
+   away from main.  Our options are: start searching from environ, but
+   that fails as soon as someone does a setenv in between.  Read the data
+   from /proc/self/auxv.  Or do the probing ourselves.  The only thing
+   extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
+   that the kernel saves all 64-bits of the registers around traps while
+   in 31-bit mode.  But this is true of all "recent" kernels (ought to dig
+   back and see from when this might not be true).  */
+
+#include <signal.h>
+
+static volatile sig_atomic_t got_sigill;
+
+static void sigill_handler(int sig)
+{
+    got_sigill = 1;
+}
+
+static void query_facilities(void)
+{
+    struct sigaction sa_old, sa_new;
+    register int r0 __asm__("0");
+    register void *r1 __asm__("1");
+    int fail;
+
+    memset(&sa_new, 0, sizeof(sa_new));
+    sa_new.sa_handler = sigill_handler;
+    sigaction(SIGILL, &sa_new, &sa_old);
+
+    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
+       we need not do any more probing.  Unfortunately, this itself is an
+       extension and the original STORE FACILITY LIST instruction is
+       kernel-only, storing its results at absolute address 200.  */
+    /* stfle 0(%r1) */
+    r1 = &facilities;
+    asm volatile(".word 0xb2b0,0x1000"
+                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
+
+    if (got_sigill) {
+        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
+           kind of instruction that we're interested in.  */
+        /* ??? Possibly some of these are in practice never present unless
+           the store-facility-extended facility is also present.  But since
+           that isn't documented it's just better to probe for each.  */
+
+        /* Test for z/Architecture.  Required even in 31-bit mode.  */
+        got_sigill = 0;
+        /* agr %r0,%r0 */
+        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
+        if (!got_sigill) {
+            facilities |= FACILITY_ZARCH | FACILITY_ZARCH_ACTIVE;
+        }
+
+        /* Test for long displacement.  */
+        got_sigill = 0;
+        /* ly %r0,0(%r1) */
+        r1 = &facilities;
+        asm volatile(".word 0xe300,0x1000,0x0058"
+                     : "=r"(r0) : "r"(r1) : "cc");
+        if (!got_sigill) {
+            facilities |= FACILITY_LONG_DISP;
+        }
+
+        /* Test for extended immediates.  */
+        got_sigill = 0;
+        /* afi %r0,0 */
+        asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
+        if (!got_sigill) {
+            facilities |= FACILITY_EXT_IMM;
+        }
+
+        /* Test for general-instructions-extension.  */
+        got_sigill = 0;
+        /* msfi %r0,1 */
+        asm volatile(".word 0xc201,0x0000,0x0001");
+        if (!got_sigill) {
+            facilities |= FACILITY_GEN_INST_EXT;
+        }
+    }
+
+    sigaction(SIGILL, &sa_old, NULL);
+
+    /* The translator currently uses these extensions unconditionally.
+       Pruning this back to the base ESA/390 architecture doesn't seem
+       worthwhile, since even the KVM target requires z/Arch.  */
+    fail = 0;
+    if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
+        fprintf(stderr, "TCG: z/Arch facility is required\n");
+        fail = 1;
+    }
+    if ((facilities & FACILITY_LONG_DISP) == 0) {
+        fprintf(stderr, "TCG: long-displacement facility is required\n");
+        fail = 1;
+    }
+    if (fail) {
+        exit(-1);
+    }
+}
+
 void tcg_target_init(TCGContext *s)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -1186,6 +1297,8 @@  void tcg_target_init(TCGContext *s)
     }
 #endif
 
+    query_facilities();
+
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);