summaryrefslogtreecommitdiffstats
path: root/driver/rdma.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2016-03-02 06:41:30 +0100
committerSuren A. Chilingaryan <csa@suren.me>2016-03-02 06:41:30 +0100
commit867bddcf7be374221a04b7ae89f93a5f5d703ee6 (patch)
treea75da5441438f10c900ea3b6b4e1d14544360a62 /driver/rdma.c
parent8933c45c177556353570f92513bb49f182ce3be8 (diff)
downloadpcitool-867bddcf7be374221a04b7ae89f93a5f5d703ee6.tar.gz
pcitool-867bddcf7be374221a04b7ae89f93a5f5d703ee6.tar.bz2
pcitool-867bddcf7be374221a04b7ae89f93a5f5d703ee6.tar.xz
pcitool-867bddcf7be374221a04b7ae89f93a5f5d703ee6.zip
Resolve user-space addresses to physical addresses in the driver
Diffstat (limited to 'driver/rdma.c')
-rw-r--r--driver/rdma.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/driver/rdma.c b/driver/rdma.c
new file mode 100644
index 0000000..22a4a5e
--- /dev/null
+++ b/driver/rdma.c
@@ -0,0 +1,53 @@
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/hugetlb.h>
+
+#include "rdma.h"
+
+static unsigned long pcidriver_follow_pte(struct mm_struct *mm, unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ spinlock_t *ptl;
+ unsigned long pfn = 0;
+
+
+ pgd = pgd_offset(mm, address);
+ if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+ return 0;
+
+ pud = pud_offset(pgd, address);
+ if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+ return 0;
+
+ pmd = pmd_offset(pud, address);
+ if (pmd_none(*pmd))
+ return 0;
+
+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (!pte_none(*pte))
+ pfn = (pte_pfn(*pte) << PAGE_SHIFT);
+ pte_unmap_unlock(pte, ptl);
+
+ return pfn;
+}
+
+unsigned long pcidriver_resolve_bar(unsigned long address) {
+ unsigned long pfn;
+
+ address = (address >> PAGE_SHIFT) << PAGE_SHIFT;
+ pfn = pcidriver_follow_pte(current->mm, address);
+
+ return pfn;
+}
+
+EXPORT_SYMBOL(pcidriver_resolve_bar);