]> xenbits.xensource.com Git - xen.git/commitdiff
xen/arm: io: Harden sign extension check
authorOleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Fri, 29 Jan 2021 01:48:48 +0000 (03:48 +0200)
committerJulien Grall <jgrall@amazon.com>
Fri, 29 Jan 2021 16:55:41 +0000 (16:55 +0000)
In the ideal world we would never get an undefined behavior when
propagating the sign bit since that bit can only be set for access
size smaller than the register size (i.e byte/half-word for aarch32,
byte/half-word/word for aarch64).

In the real world we need to care for *possible* hardware bug such as
advertising a sign extension for either 64-bit (or 32-bit) on Arm64
(resp. Arm32).

So harden a bit more the code to prevent undefined behavior when
propagating the sign bit in case of buggy hardware.

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
CC: Julien Grall <julien.grall@arm.com>
xen/include/asm-arm/traps.h

index c6b3cc75ca5d4e7e96b5a7469e6680660b14b4b4..2ed2b85c6f33460960c7abdc13c98508919e8f18 100644 (file)
@@ -94,7 +94,8 @@ static inline register_t sign_extend(const struct hsr_dabt dabt, register_t r)
      * Note that we expect the read handler to have zeroed the bits
      * outside the requested access size.
      */
-    if ( dabt.sign && (r & (1UL << (size - 1))) )
+    if ( dabt.sign && (size < sizeof(register_t) * 8) &&
+         (r & (1UL << (size - 1))) )
     {
         /*
          * We are relying on register_t using the same as