void io_free_memtype(resource_size_t start, resource_size_t end);
 
+int default_is_untracked_pat_range(u64 start, u64 end);
+
 #endif /* _ASM_X86_PAT_H */
 
 
 /**
  * struct x86_platform_ops - platform specific runtime functions
+ * @is_untracked_pat_range     exclude from PAT logic
  * @calibrate_tsc:             calibrate TSC
  * @get_wallclock:             get time from HW clock like RTC etc.
  * @set_wallclock:             set time back to HW clock
  */
 struct x86_platform_ops {
+       int (*is_untracked_pat_range)(u64 start, u64 end);
        unsigned long (*calibrate_tsc)(void);
        unsigned long (*get_wallclock)(void);
        int (*set_wallclock)(unsigned long nowtime);
 
 #include <asm/apic.h>
 #include <asm/ipi.h>
 #include <asm/smp.h>
+#include <asm/x86_init.h>
 
 DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
+static u64 gru_start_paddr, gru_end_paddr;
+
+static int is_GRU_range(u64 start, u64 end)
+{
+       return start >= gru_start_paddr && end < gru_end_paddr;
+}
+
+static int uv_is_untracked_pat_range(u64 start, u64 end)
+{
+       return is_ISA_range(start, end) || is_GRU_range(start, end);
+}
 
 static int early_get_nodeid(void)
 {
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        if (!strcmp(oem_id, "SGI")) {
+               x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
                if (!strcmp(oem_table_id, "UVL"))
                        uv_system_type = UV_LEGACY_APIC;
                else if (!strcmp(oem_table_id, "UVX"))
        int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
 
        gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
-       if (gru.s.enable)
+       if (gru.s.enable) {
                map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
+               gru_start_paddr = ((u64)gru.s.base << shift);
+               gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1);
+
+       }
 }
 
 static __init void map_mmr_high(int max_pnode)
 
 #include <asm/e820.h>
 #include <asm/time.h>
 #include <asm/irq.h>
+#include <asm/pat.h>
 #include <asm/tsc.h>
 
 void __cpuinit x86_init_noop(void) { }
 };
 
 struct x86_platform_ops x86_platform = {
+       .is_untracked_pat_range         = default_is_untracked_pat_range,
        .calibrate_tsc                  = native_calibrate_tsc,
        .get_wallclock                  = mach_get_cmos_time,
        .set_wallclock                  = mach_set_rtc_mmss,
 
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
+#include <asm/x86_init.h>
 #include <asm/pgtable.h>
 #include <asm/fcntl.h>
 #include <asm/e820.h>
        return 0;
 }
 
+int default_is_untracked_pat_range(u64 start, u64 end)
+{
+       return is_ISA_range(start, end);
+}
+
 /*
  * req_type typically has one of the:
  * - _PAGE_CACHE_WB
        }
 
        /* Low ISA region is always mapped WB in page table. No need to track */
-       if (is_ISA_range(start, end - 1)) {
+       if (x86_platform.is_untracked_pat_range(start, end - 1)) {
                if (new_type)
                        *new_type = _PAGE_CACHE_WB;
                return 0;
                return 0;
 
        /* Low ISA region is always mapped WB. No need to track */
-       if (is_ISA_range(start, end - 1))
+       if (x86_platform.is_untracked_pat_range(start, end - 1))
                return 0;
 
        is_range_ram = pat_pagerange_is_ram(start, end);
        int rettype = _PAGE_CACHE_WB;
        struct memtype *entry;
 
-       if (is_ISA_range(paddr, paddr + PAGE_SIZE - 1))
+       if (x86_platform.is_untracked_pat_range(paddr, paddr + PAGE_SIZE - 1))
                return rettype;
 
        if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) {