qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [Bug 1641861] [NEW] fail to correctly emulate FPSCR register on arm
@ 2016-11-15  7:51 Jie
  2016-11-28  9:22 ` [Qemu-devel] [Bug 1641861] " Peter Maydell
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jie @ 2016-11-15  7:51 UTC (permalink / raw)
  To: qemu-devel

Public bug reported:

Hi all, we systematically tested the QEMU implementation for emulating
arm user mode programs. We found that QEMU incorrectly emulate the FPSCR
register. The following the proof of code:

/*********** Beginning of the bug: arm.c **********/

int printf(const char *format, ...);
unsigned char i0[0x10];
unsigned char o[0x10];
int main() {
    int k = 0;
    asm("mov r2, %0\n"
        "ldr r0, [r2]\n"::"r"((char *)(i0)));;
    asm("vmsr fpscr, r0");
    asm("mov r2, %0\n"
        "vmrs r4, fpscr\n"
        "str r4, [r2]\n"::"r"((char *)(o)));;
    for (k = 0; k < 0x10; k++)
        printf("%02x", o[0x10 - 1 - k]);
    printf("\n");
}
unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};

/*********** End fo the bug **********/

When the program is compiled into arm binary code and running on a real
arm machine, and running in qemu, we have the following result

$ arm-linux-gnueabihf-gcc arm.c -o arm -static
$ ./arm
000000000000000000000000fff7009f
$ qemu-arm arm
000000000000000000000000ffffffff

According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be
reserved as zero. However, arm qemu fails to keep these bits to be zero:
these bits can be actually modified in QEMU.

QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64.

Thanks!

** Affects: qemu
     Importance: Undecided
         Status: New

** Description changed:

  Hi all, we systematically tested the QEMU implementation for emulating
  arm user mode programs. We found that QEMU incorrectly emulate the FPSCR
  register. The following the proof of code:
  
  /*********** Beginning of the bug: arm.c **********/
  
  int printf(const char *format, ...);
  unsigned char i0[0x10];
  unsigned char o[0x10];
  int main() {
-     int k = 0;
-     asm("mov r2, %0\n"
-         "ldr r0, [r2]\n"::"r"((char *)(i0)));;
-     asm("vmsr fpscr, r0");
-     asm("mov r2, %0\n"
-         "vmrs r4, fpscr\n"
-         "str r4, [r2]\n"::"r"((char *)(o)));;
-     for (k = 0; k < 0x10; k++)
-         printf("%02x", o[0x10 - 1 - k]);
-     printf("\n");
+     int k = 0;
+     asm("mov r2, %0\n"
+         "ldr r0, [r2]\n"::"r"((char *)(i0)));;
+     asm("vmsr fpscr, r0");
+     asm("mov r2, %0\n"
+         "vmrs r4, fpscr\n"
+         "str r4, [r2]\n"::"r"((char *)(o)));;
+     for (k = 0; k < 0x10; k++)
+         printf("%02x", o[0x10 - 1 - k]);
+     printf("\n");
  }
  unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};
  
  /*********** End fo the bug **********/
  
  When the program is compiled into arm binary code and running on a real
  arm machine, and running in qemu, we have the following result
  
  $ arm-linux-gnueabihf-gcc arm.c -o arm -static
  $ ./arm
  000000000000000000000000fff7009f
  $ qemu-arm arm
  000000000000000000000000ffffffff
  
  According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be
  reserved as zero. However, arm qemu fails to keep these bits to be zero:
  these bits can be actually modified in QEMU.
  
+ QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64.
+ 
  Thanks!

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1641861

Title:
  fail to correctly emulate FPSCR register on arm

Status in QEMU:
  New

Bug description:
  Hi all, we systematically tested the QEMU implementation for emulating
  arm user mode programs. We found that QEMU incorrectly emulate the
  FPSCR register. The following the proof of code:

  /*********** Beginning of the bug: arm.c **********/

  int printf(const char *format, ...);
  unsigned char i0[0x10];
  unsigned char o[0x10];
  int main() {
      int k = 0;
      asm("mov r2, %0\n"
          "ldr r0, [r2]\n"::"r"((char *)(i0)));;
      asm("vmsr fpscr, r0");
      asm("mov r2, %0\n"
          "vmrs r4, fpscr\n"
          "str r4, [r2]\n"::"r"((char *)(o)));;
      for (k = 0; k < 0x10; k++)
          printf("%02x", o[0x10 - 1 - k]);
      printf("\n");
  }
  unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};

  /*********** End fo the bug **********/

  When the program is compiled into arm binary code and running on a
  real arm machine, and running in qemu, we have the following result

  $ arm-linux-gnueabihf-gcc arm.c -o arm -static
  $ ./arm
  000000000000000000000000fff7009f
  $ qemu-arm arm
  000000000000000000000000ffffffff

  According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be
  reserved as zero. However, arm qemu fails to keep these bits to be
  zero: these bits can be actually modified in QEMU.

  QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1641861/+subscriptions

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

* [Qemu-devel] [Bug 1641861] Re: fail to correctly emulate FPSCR register on arm
  2016-11-15  7:51 [Qemu-devel] [Bug 1641861] [NEW] fail to correctly emulate FPSCR register on arm Jie
@ 2016-11-28  9:22 ` Peter Maydell
  2017-11-06 14:41 ` [Qemu-devel] [Bug 1641861] Re: ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable Peter Maydell
  2020-11-10 15:59 ` Peter Maydell
  2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2016-11-28  9:22 UTC (permalink / raw)
  To: qemu-devel

Hi. The v8 ARM ARM defines these bits of the FPSCR as "RES0". The
glossary definition of "RES0" says that for bits in a RW register it is
an implementation choice whether the bits should be "hardwired to 0" (ie
writes are ignored) or whether the bit can be written and read back (but
has no effect on behaviour). QEMU has gone for the "can be written and
read back" option.

(Previous versions of the architecture like v7 required implementations
to provide the "hardwired to 0" behaviour. In any case correctly
behaving guest code should never write 1s to these bits.)

This is a specific example of a general situation: QEMU doesn't really
pay very much attention to the edge cases of behaviour in IMPDEF or
UNPREDICTABLE cases, especially where they vary between architecture
versions, and we don't try to enforce "unimplemented always RAZ/RAO"
bits in registers. So while it might be nice to have these bits RAZ0
it's really very low priority for us -- I'd happily review and accept a
patch to do this, but am unlikely to write one myself.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1641861

Title:
  fail to correctly emulate FPSCR register on arm

Status in QEMU:
  New

Bug description:
  Hi all, we systematically tested the QEMU implementation for emulating
  arm user mode programs. We found that QEMU incorrectly emulate the
  FPSCR register. The following the proof of code:

  /*********** Beginning of the bug: arm.c **********/

  int printf(const char *format, ...);
  unsigned char i0[0x10];
  unsigned char o[0x10];
  int main() {
      int k = 0;
      asm("mov r2, %0\n"
          "ldr r0, [r2]\n"::"r"((char *)(i0)));;
      asm("vmsr fpscr, r0");
      asm("mov r2, %0\n"
          "vmrs r4, fpscr\n"
          "str r4, [r2]\n"::"r"((char *)(o)));;
      for (k = 0; k < 0x10; k++)
          printf("%02x", o[0x10 - 1 - k]);
      printf("\n");
  }
  unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};

  /*********** End fo the bug **********/

  When the program is compiled into arm binary code and running on a
  real arm machine, and running in qemu, we have the following result

  $ arm-linux-gnueabihf-gcc arm.c -o arm -static
  $ ./arm
  000000000000000000000000fff7009f
  $ qemu-arm arm
  000000000000000000000000ffffffff

  According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be
  reserved as zero. However, arm qemu fails to keep these bits to be
  zero: these bits can be actually modified in QEMU.

  QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1641861/+subscriptions

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

* [Qemu-devel] [Bug 1641861] Re: ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable
  2016-11-15  7:51 [Qemu-devel] [Bug 1641861] [NEW] fail to correctly emulate FPSCR register on arm Jie
  2016-11-28  9:22 ` [Qemu-devel] [Bug 1641861] " Peter Maydell
@ 2017-11-06 14:41 ` Peter Maydell
  2020-11-10 15:59 ` Peter Maydell
  2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2017-11-06 14:41 UTC (permalink / raw)
  To: qemu-devel

** Summary changed:

- fail to correctly emulate FPSCR register on arm
+ ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable

** Changed in: qemu
       Status: New => Confirmed

** Tags added: arm

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1641861

Title:
  ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable

Status in QEMU:
  Confirmed

Bug description:
  Hi all, we systematically tested the QEMU implementation for emulating
  arm user mode programs. We found that QEMU incorrectly emulate the
  FPSCR register. The following the proof of code:

  /*********** Beginning of the bug: arm.c **********/

  int printf(const char *format, ...);
  unsigned char i0[0x10];
  unsigned char o[0x10];
  int main() {
      int k = 0;
      asm("mov r2, %0\n"
          "ldr r0, [r2]\n"::"r"((char *)(i0)));;
      asm("vmsr fpscr, r0");
      asm("mov r2, %0\n"
          "vmrs r4, fpscr\n"
          "str r4, [r2]\n"::"r"((char *)(o)));;
      for (k = 0; k < 0x10; k++)
          printf("%02x", o[0x10 - 1 - k]);
      printf("\n");
  }
  unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};

  /*********** End fo the bug **********/

  When the program is compiled into arm binary code and running on a
  real arm machine, and running in qemu, we have the following result

  $ arm-linux-gnueabihf-gcc arm.c -o arm -static
  $ ./arm
  000000000000000000000000fff7009f
  $ qemu-arm arm
  000000000000000000000000ffffffff

  According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be
  reserved as zero. However, arm qemu fails to keep these bits to be
  zero: these bits can be actually modified in QEMU.

  QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1641861/+subscriptions

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

* [Bug 1641861] Re: ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable
  2016-11-15  7:51 [Qemu-devel] [Bug 1641861] [NEW] fail to correctly emulate FPSCR register on arm Jie
  2016-11-28  9:22 ` [Qemu-devel] [Bug 1641861] " Peter Maydell
  2017-11-06 14:41 ` [Qemu-devel] [Bug 1641861] Re: ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable Peter Maydell
@ 2020-11-10 15:59 ` Peter Maydell
  2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2020-11-10 15:59 UTC (permalink / raw)
  To: qemu-devel

QEMU now does enforce these RES0 bits. I had to fix up the inline asm
syntax in the example guest program (which was missing a clobbers list
and generally didn't work with newer gcc):

int printf(const char *format, ...);
unsigned char i0[0x10];
unsigned char o[0x10];
int main() {
    int k;
    asm volatile ("mov r2, %0\n"
        "ldr r0, [r2]\n"
        "vmsr fpscr, r0\n"
        "mov r2, %1\n"
        "vmrs r4, fpscr\n"
        "str r4, [r2]\n" :: "r"((char *)(i0)), "r"((char *)(o)) : "r2", "r4", "memory");

    for (k = 0; k < 0x10; k++) {
        printf("%02x", o[0x10 - 1 - k]);
    }
    printf("\n");
}
unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};

but it now prints:
000000000000000000000000ffff009f

which is the same as the quoted hardware value except that QEMU supports fp16 arithmetic and so bit 19 (FZ16) is writable. CPUs without fp16 behave as expected:
qemu-arm -cpu cortex-a9 /tmp/arm
000000000000000000000000fff7009f


** Changed in: qemu
       Status: Confirmed => Fix Released

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1641861

Title:
  ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable

Status in QEMU:
  Fix Released

Bug description:
  Hi all, we systematically tested the QEMU implementation for emulating
  arm user mode programs. We found that QEMU incorrectly emulate the
  FPSCR register. The following the proof of code:

  /*********** Beginning of the bug: arm.c **********/

  int printf(const char *format, ...);
  unsigned char i0[0x10];
  unsigned char o[0x10];
  int main() {
      int k = 0;
      asm("mov r2, %0\n"
          "ldr r0, [r2]\n"::"r"((char *)(i0)));;
      asm("vmsr fpscr, r0");
      asm("mov r2, %0\n"
          "vmrs r4, fpscr\n"
          "str r4, [r2]\n"::"r"((char *)(o)));;
      for (k = 0; k < 0x10; k++)
          printf("%02x", o[0x10 - 1 - k]);
      printf("\n");
  }
  unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00};

  /*********** End fo the bug **********/

  When the program is compiled into arm binary code and running on a
  real arm machine, and running in qemu, we have the following result

  $ arm-linux-gnueabihf-gcc arm.c -o arm -static
  $ ./arm
  000000000000000000000000fff7009f
  $ qemu-arm arm
  000000000000000000000000ffffffff

  According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be
  reserved as zero. However, arm qemu fails to keep these bits to be
  zero: these bits can be actually modified in QEMU.

  QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64.

  Thanks!

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1641861/+subscriptions


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

end of thread, other threads:[~2020-11-10 16:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-15  7:51 [Qemu-devel] [Bug 1641861] [NEW] fail to correctly emulate FPSCR register on arm Jie
2016-11-28  9:22 ` [Qemu-devel] [Bug 1641861] " Peter Maydell
2017-11-06 14:41 ` [Qemu-devel] [Bug 1641861] Re: ARM QEMU doesn't enforce that RES0 bits in FPSCR are non-writeable Peter Maydell
2020-11-10 15:59 ` Peter Maydell

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).