Page MenuHomeFreeBSD

D33561.diff
No OneTemporary

D33561.diff

diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h
--- a/sys/compat/linuxkpi/common/include/linux/io.h
+++ b/sys/compat/linuxkpi/common/include/linux/io.h
@@ -482,4 +482,12 @@
iounmap(addr);
}
+#define __MTRR_ID_BASE 1
+int lkpi_arch_phys_wc_add(unsigned long, unsigned long);
+void lkpi_arch_phys_wc_del(int);
+#define arch_phys_wc_add(...) lkpi_arch_phys_wc_add(__VA_ARGS__)
+#define arch_phys_wc_del(...) lkpi_arch_phys_wc_del(__VA_ARGS__)
+#define arch_phys_wc_index(x) \
+ (((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE))
+
#endif /* _LINUX_IO_H_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c
--- a/sys/compat/linuxkpi/common/src/linux_page.c
+++ b/sys/compat/linuxkpi/common/src/linux_page.c
@@ -39,6 +39,7 @@
#include <sys/rwlock.h>
#include <sys/proc.h>
#include <sys/sched.h>
+#include <sys/memrange.h>
#include <machine/bus.h>
@@ -63,6 +64,15 @@
#include <linux/preempt.h>
#include <linux/fs.h>
#include <linux/shmem_fs.h>
+#include <linux/kernel.h>
+#include <linux/idr.h>
+#include <linux/io.h>
+
+#ifdef __i386__
+DEFINE_IDR(mtrr_idr);
+static MALLOC_DEFINE(M_LKMTRR, "idr", "Linux MTRR compat");
+extern int pat_works;
+#endif
void
si_meminfo(struct sysinfo *si)
@@ -357,3 +367,65 @@
vm_object_deallocate(devobj);
}
}
+
+int
+lkpi_arch_phys_wc_add(unsigned long base, unsigned long size)
+{
+#ifdef __i386__
+ struct mem_range_desc *mrdesc;
+ int error, id, act;
+
+ /* If PAT is available, do nothing */
+ if (pat_works)
+ return (0);
+
+ mrdesc = malloc(sizeof(*mrdesc), M_LKMTRR, M_WAITOK);
+ mrdesc->mr_base = base;
+ mrdesc->mr_len = size;
+ mrdesc->mr_flags = MDF_WRITECOMBINE;
+ strlcpy(mrdesc->mr_owner, "drm", sizeof(mrdesc->mr_owner));
+ act = MEMRANGE_SET_UPDATE;
+ error = mem_range_attr_set(mrdesc, &act);
+ if (error == 0) {
+ error = idr_get_new(&mtrr_idr, mrdesc, &id);
+ MPASS(idr_find(&mtrr_idr, id) == mrdesc);
+ if (error != 0) {
+ act = MEMRANGE_SET_REMOVE;
+ mem_range_attr_set(mrdesc, &act);
+ }
+ }
+ if (error != 0) {
+ free(mrdesc, M_LKMTRR);
+ pr_warn(
+ "Failed to add WC MTRR for [%p-%p]: %d; "
+ "performance may suffer\n",
+ (void *)base, (void *)(base + size - 1), error);
+ } else
+ pr_warn("Successfully added WC MTRR for [%p-%p]\n",
+ (void *)base, (void *)(base + size - 1));
+
+ return (error != 0 ? -error : id + __MTRR_ID_BASE);
+#else
+ return (0);
+#endif
+}
+
+void
+lkpi_arch_phys_wc_del(int reg)
+{
+#ifdef __i386__
+ struct mem_range_desc *mrdesc;
+ int act;
+
+ /* Check if arch_phys_wc_add() failed. */
+ if (reg < __MTRR_ID_BASE)
+ return;
+
+ mrdesc = idr_find(&mtrr_idr, reg - __MTRR_ID_BASE);
+ MPASS(mrdesc != NULL);
+ idr_remove(&mtrr_idr, reg - __MTRR_ID_BASE);
+ act = MEMRANGE_SET_REMOVE;
+ mem_range_attr_set(mrdesc, &act);
+ free(mrdesc, M_LKMTRR);
+#endif
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 21, 12:23 PM (21 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14761306
Default Alt Text
D33561.diff (2 KB)

Event Timeline