target/ppc: Correct SDR1 masking
authorDavid Gibson <david@gibson.dropbear.id.au>
Fri, 24 Feb 2017 06:35:50 +0000 (17:35 +1100)
committerDavid Gibson <david@gibson.dropbear.id.au>
Wed, 1 Mar 2017 00:23:39 +0000 (11:23 +1100)
SDR_64_HTABORG, which indicates the bits of the SDR1 register to use for
the base of a 64-bit machine's hashed page table (HPT) isn't correct.  It
includes the top 46 bits of the register, but in fact the top 4 bits must
be zero (according to the ISA v2.07).  No actual implementation has
supported close to 2^60 bytes of physical address space, so it's kind of
irrelevant, but we might as well correct this.

In addition, although we checked for bad size values in SDR1, we never
reported an error if entirely invalid bits were set there.  Add this check
to ppc_store_sdr1().

Reported-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
target/ppc/mmu-hash64.h
target/ppc/mmu_helper.c

index 9c74823f92308fd18896cc15e5ef664375694132..54f1e37655a5c2fee66aa3fd4bfd67819eb845c9 100644 (file)
@@ -56,7 +56,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
  * Hash page table definitions
  */
 
-#define SDR_64_HTABORG         0xFFFFFFFFFFFC0000ULL
+#define SDR_64_HTABORG         0x0FFFFFFFFFFC0000ULL
 #define SDR_64_HTABSIZE        0x000000000000001FULL
 
 #define HPTES_PER_GROUP         8
index 3bc80303e9a67c844be2c6be27b4890beb018e91..a1af3d6bf23999b05bffff66ce5df87ff53ad531 100644 (file)
@@ -2007,8 +2007,14 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
     assert(!cpu->vhyp);
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64) {
+        target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
         target_ulong htabsize = value & SDR_64_HTABSIZE;
 
+        if (value & ~sdr_mask) {
+            error_report("Invalid bits 0x"TARGET_FMT_lx" set in SDR1",
+                         value & ~sdr_mask);
+            value &= sdr_mask;
+        }
         if (htabsize > 28) {
             error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1",
                          htabsize);