[PATCH 01/12] MIPS: Fix definition of KSEGX() for 64-bit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The KSEGX() macro is defined to 32-bit sign extend the address argument
and logically AND the result with 0xe0000000, with the final result
usually compared against one of the CKSEG macros. However the literal
0xe0000000 is unsigned as the high bit is set, and is therefore
zero-extended on 64-bit kernels, resulting in the sign extension bits of
the argument being masked to zero. This results in the odd situation
where:

  KSEGX(CKSEG) != CKSEG
  (0xffffffff80000000 & 0x00000000e0000000) != 0xffffffff80000000)

Fix this by 32-bit sign extending the 0xe0000000 literal using
_ACAST32_.

This will help some MIPS KVM code handling 32-bit guest addresses to
work on 64-bit host kernels, but will also affect KSEGX in
dec_kn01_be_backend() on a 64-bit DECstation kernel, and the SiByte DMA
page ops KSEGX check in clear_page() and copy_page() on 64-bit SB1
kernels, neither of which appear to be designed with 64-bit segments in
mind anyway.

Signed-off-by: James Hogan <james.hogan@xxxxxxxxxx>
Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx>
Cc: Maciej W. Rozycki <macro@xxxxxxxxxxxxxx>
Cc: linux-mips@xxxxxxxxxxxxxx
---
For the SiByte optimisations in arch/mips/mm/page.c, the KSEGX condition
looks slightly questionable anyway - is it acceptable to 32-bit sign
extend the pointer in that case before the comparison. Currently the
effect of the zero-extended 0xe0000000 is to prevent the optimisation
from happening on 64-bit kernels. Will this patch cause breakage due to
the pointer possibly being in some other 64-bit segment and the
optimisation suddenly being enabled?

As for the DEC bus error handling usage, it doesn't seem to take 64-bit
addresses into account anyway (which get 32-bit sign extended by KSEGX).
The effect of the zero-extended 0xe0000000 is to cause the TLB lookup
code to always take place with no TLB presence check, which seems
already broken.
---
 arch/mips/include/asm/addrspace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
index 3b0e51d5a613..c5b04e752e97 100644
--- a/arch/mips/include/asm/addrspace.h
+++ b/arch/mips/include/asm/addrspace.h
@@ -45,7 +45,7 @@
 /*
  * Returns the kernel segment base of a given address
  */
-#define KSEGX(a)		((_ACAST32_ (a)) & 0xe0000000)
+#define KSEGX(a)		((_ACAST32_(a)) & _ACAST32_(0xe0000000))
 
 /*
  * Returns the physical address of a CKSEGx / XKPHYS address
-- 
2.4.10





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux