aboutsummaryrefslogtreecommitdiff
path: root/sys/powerpc
diff options
context:
space:
mode:
authorPeter Grehan <grehan@FreeBSD.org>2006-12-05 04:01:52 +0000
committerPeter Grehan <grehan@FreeBSD.org>2006-12-05 04:01:52 +0000
commit6e4f008cbb324b4a9e44de14f01694f4a8f9a659 (patch)
tree3403144535091ef5fcdb4c1243c91d984e07d700 /sys/powerpc
parent2afca7acfbe0a2f96b2ca855e0f789eaa56cad0b (diff)
Notes
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/aim/mmu_oea.c8
-rw-r--r--sys/powerpc/aim/uio_machdep.c6
-rw-r--r--sys/powerpc/include/pmap.h2
-rw-r--r--sys/powerpc/powerpc/mmu_if.m14
-rw-r--r--sys/powerpc/powerpc/mmu_oea.c8
-rw-r--r--sys/powerpc/powerpc/pmap_dispatch.c5
-rw-r--r--sys/powerpc/powerpc/uio_machdep.c6
7 files changed, 46 insertions, 3 deletions
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 182702f96850..ec13d0667b63 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -342,6 +342,7 @@ void moea_unmapdev(mmu_t, vm_offset_t, vm_size_t);
vm_offset_t moea_kextract(mmu_t, vm_offset_t);
void moea_kenter(mmu_t, vm_offset_t, vm_offset_t);
boolean_t moea_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
+boolean_t moea_page_executable(mmu_t, vm_page_t);
static mmu_method_t moea_methods[] = {
MMUMETHOD(mmu_change_wiring, moea_change_wiring),
@@ -380,6 +381,7 @@ static mmu_method_t moea_methods[] = {
MMUMETHOD(mmu_kextract, moea_kextract),
MMUMETHOD(mmu_kenter, moea_kenter),
MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped),
+ MMUMETHOD(mmu_page_executable, moea_page_executable),
{ 0, 0 }
};
@@ -2453,6 +2455,12 @@ moea_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
return (EFAULT);
}
+boolean_t
+moea_page_executable(mmu_t mmu, vm_page_t pg)
+{
+ return ((moea_attr_fetch(pg) & PTE_EXEC) == PTE_EXEC);
+}
+
/*
* Map a set of physical memory pages into the kernel virtual
* address space. Return a pointer to where it is mapped. This
diff --git a/sys/powerpc/aim/uio_machdep.c b/sys/powerpc/aim/uio_machdep.c
index bd2f1b447e81..a52f72920a73 100644
--- a/sys/powerpc/aim/uio_machdep.c
+++ b/sys/powerpc/aim/uio_machdep.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include <machine/cpu.h>
#include <machine/vmparam.h>
/*
@@ -92,10 +93,13 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
uio_yield();
if (uio->uio_rw == UIO_READ)
error = copyout(cp, iov->iov_base, cnt);
- else
+ else
error = copyin(iov->iov_base, cp, cnt);
if (error)
goto out;
+ if (uio->uio_rw == UIO_WRITE &&
+ pmap_page_executable(ma[offset >> PAGE_SHIFT]))
+ __syncicache(cp, cnt);
break;
case UIO_SYSSPACE:
if (uio->uio_rw == UIO_READ)
diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h
index 213d2113dcfb..d02f8d646c06 100644
--- a/sys/powerpc/include/pmap.h
+++ b/sys/powerpc/include/pmap.h
@@ -95,7 +95,7 @@ void pmap_unmapdev(vm_offset_t, vm_size_t);
void pmap_deactivate(struct thread *);
vm_offset_t pmap_kextract(vm_offset_t);
int pmap_dev_direct_mapped(vm_offset_t, vm_size_t);
-
+boolean_t pmap_page_executable(vm_page_t);
boolean_t pmap_mmu_install(char *name, int prio);
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
diff --git a/sys/powerpc/powerpc/mmu_if.m b/sys/powerpc/powerpc/mmu_if.m
index 548660f6c075..0fc546fb14b2 100644
--- a/sys/powerpc/powerpc/mmu_if.m
+++ b/sys/powerpc/powerpc/mmu_if.m
@@ -752,3 +752,17 @@ METHOD boolean_t dev_direct_mapped {
vm_offset_t _pa;
vm_size_t _size;
};
+
+
+/**
+ * @brief Evaluate if a physical page has an executable mapping
+ *
+ * @param _pg physical page
+ *
+ * @retval bool TRUE if a physical mapping exists for the given page.
+ */
+METHOD boolean_t page_executable {
+ mmu_t _mmu;
+ vm_page_t _pg;
+};
+
diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c
index 182702f96850..ec13d0667b63 100644
--- a/sys/powerpc/powerpc/mmu_oea.c
+++ b/sys/powerpc/powerpc/mmu_oea.c
@@ -342,6 +342,7 @@ void moea_unmapdev(mmu_t, vm_offset_t, vm_size_t);
vm_offset_t moea_kextract(mmu_t, vm_offset_t);
void moea_kenter(mmu_t, vm_offset_t, vm_offset_t);
boolean_t moea_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
+boolean_t moea_page_executable(mmu_t, vm_page_t);
static mmu_method_t moea_methods[] = {
MMUMETHOD(mmu_change_wiring, moea_change_wiring),
@@ -380,6 +381,7 @@ static mmu_method_t moea_methods[] = {
MMUMETHOD(mmu_kextract, moea_kextract),
MMUMETHOD(mmu_kenter, moea_kenter),
MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped),
+ MMUMETHOD(mmu_page_executable, moea_page_executable),
{ 0, 0 }
};
@@ -2453,6 +2455,12 @@ moea_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
return (EFAULT);
}
+boolean_t
+moea_page_executable(mmu_t mmu, vm_page_t pg)
+{
+ return ((moea_attr_fetch(pg) & PTE_EXEC) == PTE_EXEC);
+}
+
/*
* Map a set of physical memory pages into the kernel virtual
* address space. Return a pointer to where it is mapped. This
diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c
index c0762cfc24a5..92ac5148a404 100644
--- a/sys/powerpc/powerpc/pmap_dispatch.c
+++ b/sys/powerpc/powerpc/pmap_dispatch.c
@@ -345,6 +345,11 @@ pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size));
}
+boolean_t
+pmap_page_executable(vm_page_t pg)
+{
+ return (MMU_PAGE_EXECUTABLE(mmu_obj, pg));
+}
/*
* MMU install routines. Highest priority wins, equal priority also
diff --git a/sys/powerpc/powerpc/uio_machdep.c b/sys/powerpc/powerpc/uio_machdep.c
index bd2f1b447e81..a52f72920a73 100644
--- a/sys/powerpc/powerpc/uio_machdep.c
+++ b/sys/powerpc/powerpc/uio_machdep.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include <machine/cpu.h>
#include <machine/vmparam.h>
/*
@@ -92,10 +93,13 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
uio_yield();
if (uio->uio_rw == UIO_READ)
error = copyout(cp, iov->iov_base, cnt);
- else
+ else
error = copyin(iov->iov_base, cp, cnt);
if (error)
goto out;
+ if (uio->uio_rw == UIO_WRITE &&
+ pmap_page_executable(ma[offset >> PAGE_SHIFT]))
+ __syncicache(cp, cnt);
break;
case UIO_SYSSPACE:
if (uio->uio_rw == UIO_READ)