summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/pmap.c7
-rw-r--r--sys/i386/i386/pmap.c11
-rw-r--r--sys/i386/xen/pmap.c19
-rw-r--r--sys/vm/device_pager.c16
4 files changed, 34 insertions, 19 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 99f55cb..265d77d 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -4381,9 +4381,12 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
m->md.pat_mode = ma;
/*
- * Update the direct mapping and flush the cache.
+ * If "m" is a normal page, update its direct mapping. This update
+ * can be relied upon to perform any cache operations that are
+ * required for data coherence.
*/
- if (pmap_change_attr(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)), PAGE_SIZE,
+ if ((m->flags & PG_FICTITIOUS) == 0 &&
+ pmap_change_attr(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)), PAGE_SIZE,
m->md.pat_mode))
panic("memory attribute change on the direct map failed");
}
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 6103fd5..b973d0d 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -4466,12 +4466,13 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
m->md.pat_mode = ma;
/*
- * Flush CPU caches to make sure any data isn't cached that shouldn't
- * be, etc.
+ * If "m" is a normal page, flush it from the cache.
*/
- /* If "Self Snoop" is supported, do nothing. */
- if (!(cpu_feature & CPUID_SS))
- pmap_invalidate_cache();
+ if ((m->flags & PG_FICTITIOUS) == 0) {
+ /* If "Self Snoop" is supported, do nothing. */
+ if (!(cpu_feature & CPUID_SS))
+ pmap_invalidate_cache();
+ }
}
int
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index 9a9a1b4..051685a 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -3921,6 +3921,25 @@ pmap_unmapdev(vm_offset_t va, vm_size_t size)
kmem_free(kernel_map, base, size);
}
+/*
+ * Sets the memory attribute for the specified page.
+ */
+void
+pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
+{
+
+ m->md.pat_mode = ma;
+
+ /*
+ * If "m" is a normal page, flush it from the cache.
+ */
+ if ((m->flags & PG_FICTITIOUS) == 0) {
+ /* If "Self Snoop" is supported, do nothing. */
+ if (!(cpu_feature & CPUID_SS))
+ pmap_invalidate_cache();
+ }
+}
+
int
pmap_change_attr(va, size, mode)
vm_offset_t va;
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 7993405..0d762de 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -305,7 +305,8 @@ dev_pager_haspage(object, pindex, before, after)
/*
* Create a fictitious page with the specified physical address and memory
- * attribute.
+ * attribute. The memory attribute is the only the machine-dependent aspect
+ * of a fictitious page that must be initialized.
*/
static vm_page_t
dev_pager_getfake(vm_paddr_t paddr, vm_memattr_t memattr)
@@ -317,11 +318,9 @@ dev_pager_getfake(vm_paddr_t paddr, vm_memattr_t memattr)
/* Fictitious pages don't use "segind". */
m->flags = PG_FICTITIOUS;
/* Fictitious pages don't use "order" or "pool". */
- pmap_page_init(m);
m->oflags = VPO_BUSY;
m->wire_count = 1;
- if (memattr != VM_MEMATTR_DEFAULT)
- pmap_page_set_memattr(m, memattr);
+ pmap_page_set_memattr(m, memattr);
return (m);
}
@@ -334,9 +333,6 @@ dev_pager_putfake(vm_page_t m)
if (!(m->flags & PG_FICTITIOUS))
panic("dev_pager_putfake: bad page");
- /* Restore the default memory attribute to "phys_addr". */
- if (pmap_page_get_memattr(m) != VM_MEMATTR_DEFAULT)
- pmap_page_set_memattr(m, VM_MEMATTR_DEFAULT);
uma_zfree(fakepg_zone, m);
}
@@ -350,10 +346,6 @@ dev_pager_updatefake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr)
if (!(m->flags & PG_FICTITIOUS))
panic("dev_pager_updatefake: bad page");
- /* Restore the default memory attribute before changing "phys_addr". */
- if (pmap_page_get_memattr(m) != VM_MEMATTR_DEFAULT)
- pmap_page_set_memattr(m, VM_MEMATTR_DEFAULT);
m->phys_addr = paddr;
- if (memattr != VM_MEMATTR_DEFAULT)
- pmap_page_set_memattr(m, memattr);
+ pmap_page_set_memattr(m, memattr);
}
OpenPOWER on IntegriCloud