graphene-ipc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. #include <linux/module.h>
  2. #include <linux/kallsyms.h>
  3. #include <linux/version.h>
  4. #include <linux/init.h>
  5. #include <linux/fs.h>
  6. #include <linux/mm_types.h>
  7. #include <linux/mm.h>
  8. #include <linux/mmu_notifier.h>
  9. #include <linux/slab.h>
  10. #include <linux/swap.h>
  11. #include <linux/swapops.h>
  12. #include <linux/miscdevice.h>
  13. #include <linux/sched.h>
  14. #include <linux/pagemap.h>
  15. #include <linux/bitmap.h>
  16. #include <asm/mman.h>
  17. #include <asm/tlb.h>
  18. #ifdef CONFIG_GRAPHENE_BULK_IPC
  19. # include "graphene.h"
  20. #endif
  21. #include "graphene-ipc.h"
  22. MODULE_LICENSE("Dual BSD/GPL");
  23. #define FILE_POISON LIST_POISON1
  24. struct kmem_cache *gipc_queue_cachep;
  25. struct kmem_cache *gipc_send_buffer_cachep;
  26. #define GIPC_DEBUG 0
  27. #if defined(GIPC_DEBUG) && GIPC_DEBUG == 1
  28. # define DEBUG(...) printk(KERN_INFO __VA_ARGS__)
  29. # define GIPC_BUG_ON(cond) BUG_ON(cond)
  30. #else
  31. # define DEBUG(...)
  32. # define GIPC_BUG_ON(cond)
  33. #endif
  34. #define LOOKUP_KALLSYMS(sym) \
  35. do { \
  36. my_##sym = (void *) kallsyms_lookup_name(#sym); \
  37. if (!my_##sym) { \
  38. printk(KERN_ERR "Graphene error: " \
  39. "can't find kernel function " #sym "\n");\
  40. return -ENOENT; \
  41. } else { \
  42. printk(KERN_INFO "resolved symbol " #sym " %p\n", \
  43. my_##sym); \
  44. } \
  45. } while (0)
  46. #if defined(CONFIG_GRAPHENE_BULK_IPC) || LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
  47. # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
  48. # define DO_MMAP_PGOFF(file, addr, len, prot, flags, pgoff) \
  49. ({ \
  50. unsigned long populate; \
  51. unsigned long rv = do_mmap_pgoff((file), (addr), (len), \
  52. (prot), (flags), \
  53. (pgoff), &populate); \
  54. rv; })
  55. # else
  56. # define DO_MMAP_PGOFF(file, addr, len, prot, flags, pgoff) \
  57. do_mmap_pgoff((file), (addr), (len), (prot), (flags), (pgoff))
  58. # endif /* kernel_version < 3.9.0 */
  59. #else
  60. # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
  61. # define MY_DO_MMAP_PGOFF
  62. unsigned long (*my_do_mmap_pgoff) (struct file *, unsigned long,
  63. unsigned long, unsigned long,
  64. unsigned long, unsigned long,
  65. unsigned long *);
  66. # define DO_MMAP_PGOFF(file, addr, len, prot, flags, pgoff) \
  67. ({ \
  68. unsigned long populate; \
  69. unsigned long rv = my_do_mmap_pgoff((file), (addr), \
  70. (len), (prot), \
  71. (flags), (pgoff), \
  72. &populate); \
  73. rv; })
  74. # else
  75. # define MY_DO_MMAP_PGOFF
  76. unsigned long (*my_do_mmap_pgoff) (struct file *, unsigned long,
  77. unsigned long, unsigned long,
  78. unsigned long, unsigned long);
  79. # define DO_MMAP_PGOFF(file, addr, len, prot, flags, pgoff) \
  80. my_do_mmap_pgoff((file), (addr), (len), (prot), (flags), (pgoff))
  81. # endif /* kernel version < 3.9 */
  82. #endif /* !CONFIG_GRAPHENE_BULK_IPC && kernel version > 3.4.0 */
  83. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
  84. # ifdef CONFIG_GRAPHENE_BULK_IPC
  85. # define FLUSH_TLB_MM_RANGE flush_tlb_mm_range
  86. # else
  87. # define MY_FLUSH_TLB_MM_RANGE
  88. void (*my_flush_tlb_mm_range) (struct mm_struct *, unsigned long,
  89. unsigned long, unsigned long);
  90. # define FLUSH_TLB_MM_RANGE my_flush_tlb_mm_range
  91. # endif
  92. #else /* LINUX_VERSION_CODE < 3.7.0 */
  93. # if defined(CONFIG_GRAPHENE_BULK_IPC) || LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
  94. # define FLUSH_TLB_PAGE flush_tlb_page
  95. # else
  96. # define MY_FLUSH_TLB_PAGE
  97. void (*my_flush_tlb_page) (struct vm_area_struct *, unsigned long);
  98. # define FLUSH_TLB_PAGE my_flush_tlb_page
  99. # endif
  100. #endif
  101. #ifndef gipc_get_session
  102. u64 (*my_gipc_get_session) (struct task_struct *) = NULL;
  103. #endif
  104. struct gipc_queue {
  105. struct list_head list;
  106. s64 token;
  107. u64 owner;
  108. atomic_t count;
  109. struct mutex send_lock, recv_lock;
  110. wait_queue_head_t send, recv;
  111. volatile int next, last;
  112. struct {
  113. struct page *page;
  114. struct file *file;
  115. u64 pgoff;
  116. } pages[PAGE_QUEUE];
  117. };
  118. struct gipc_send_buffer {
  119. unsigned long page_bit_map[PAGE_BITS];
  120. struct page *pages[PAGE_QUEUE];
  121. struct vm_area_struct *vmas[PAGE_QUEUE];
  122. struct file *files[PAGE_QUEUE];
  123. unsigned long pgoffs[PAGE_QUEUE];
  124. };
  125. struct {
  126. spinlock_t lock;
  127. /*
  128. * For now, just make them monotonically increasing. XXX: At
  129. * some point, do something smarter for security.
  130. */
  131. u64 max_token;
  132. struct list_head channels; // gipc_queue structs
  133. } gdev;
  134. #ifdef gipc_get_session
  135. #define GIPC_OWNER gipc_get_session(current)
  136. #else
  137. #define GIPC_OWNER (my_gipc_get_session ? my_gipc_get_session(current) : 0)
  138. #endif
  139. static inline struct gipc_queue * create_gipc_queue(struct file *creator)
  140. {
  141. struct gipc_queue *gq = kmem_cache_alloc(gipc_queue_cachep, GFP_KERNEL);
  142. if (!gq)
  143. return gq;
  144. memset(gq, 0, sizeof(*gq));
  145. INIT_LIST_HEAD(&gq->list);
  146. mutex_init(&gq->send_lock);
  147. mutex_init(&gq->recv_lock);
  148. init_waitqueue_head(&gq->send);
  149. init_waitqueue_head(&gq->recv);
  150. gq->owner = GIPC_OWNER;
  151. creator->private_data = gq;
  152. atomic_set(&gq->count, 1);
  153. spin_lock(&gdev.lock);
  154. list_add(&gq->list, &gdev.channels);
  155. gq->token = gdev.max_token++;
  156. spin_unlock(&gdev.lock);
  157. return gq;
  158. }
  159. static inline void release_gipc_queue(struct gipc_queue *gq, bool locked)
  160. {
  161. int idx;
  162. if (!atomic_dec_and_test(&gq->count))
  163. return;
  164. if (!locked)
  165. spin_lock(&gdev.lock);
  166. while (gq->next != gq->last) {
  167. idx = gq->next;
  168. if (gq->pages[idx].page) {
  169. page_cache_release(gq->pages[idx].page);
  170. gq->pages[idx].page = NULL;
  171. }
  172. if (gq->pages[idx].file) {
  173. fput_atomic(gq->pages[idx].file);
  174. gq->pages[idx].file = NULL;
  175. gq->pages[idx].pgoff = 0;
  176. }
  177. gq->next++;
  178. gq->next &= (PAGE_QUEUE - 1);
  179. }
  180. list_del(&gq->list);
  181. if (!locked)
  182. spin_unlock(&gdev.lock);
  183. kmem_cache_free(gipc_queue_cachep, gq);
  184. }
  185. #if defined(SPLIT_RSS_COUNTING)
  186. static void add_mm_counter_fast(struct mm_struct *mm, int member, int val)
  187. {
  188. struct task_struct *task = current;
  189. if (likely(task->mm == mm))
  190. task->rss_stat.count[member] += val;
  191. else
  192. add_mm_counter(mm, member, val);
  193. }
  194. #else
  195. #define add_mm_counter_fast(mm, member, val) add_mm_counter(mm, member, val)
  196. #endif
  197. #define inc_mm_counter_fast(mm, member) add_mm_counter_fast(mm, member, 1)
  198. #define dec_mm_counter_fast(mm, member) add_mm_counter_fast(mm, member, -1)
  199. inline int make_page_cow(struct mm_struct *mm, struct vm_area_struct *vma,
  200. unsigned long addr)
  201. {
  202. pgd_t *pgd;
  203. pud_t *pud;
  204. pmd_t *pmd;
  205. pte_t *pte;
  206. spinlock_t *ptl;
  207. pgd = pgd_offset(mm, addr);
  208. if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
  209. goto no_page;
  210. pud = pud_offset(pgd, addr);
  211. if (pud_none(*pud) || unlikely(pud_bad(*pud)))
  212. goto no_page;
  213. pmd = pmd_offset(pud, addr);
  214. if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
  215. goto no_page;
  216. BUG_ON(pmd_trans_huge(*pmd));
  217. pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
  218. if (!pte_present(*pte)) {
  219. spin_unlock(ptl);
  220. goto no_page;
  221. }
  222. ptep_set_wrprotect(mm, addr, pte);
  223. spin_unlock(ptl);
  224. DEBUG("make page COW at %lx\n", addr);
  225. return 0;
  226. no_page:
  227. return -EFAULT;
  228. }
  229. static void fill_page_bit_map(struct mm_struct *mm,
  230. unsigned long addr, unsigned long nr_pages,
  231. unsigned long page_bit_map[PAGE_BITS])
  232. {
  233. int i = 0;
  234. DEBUG("GIPC_SEND fill_page_bit_map %lx - %lx\n",
  235. addr, addr + (nr_pages << PAGE_SHIFT));
  236. do {
  237. struct vm_area_struct *vma;
  238. pgd_t *pgd;
  239. pud_t *pud;
  240. pmd_t *pmd;
  241. pte_t *pte;
  242. spinlock_t *ptl;
  243. bool has_page = false;
  244. vma = find_vma(mm, addr);
  245. if (!vma)
  246. goto next;
  247. BUG_ON(vma->vm_flags & VM_HUGETLB);
  248. pgd = pgd_offset(mm, addr);
  249. if (pgd_none(*pgd) || pgd_bad(*pgd))
  250. goto next;
  251. pud = pud_offset(pgd, addr);
  252. if (pud_none(*pud) || pud_bad(*pud))
  253. goto next;
  254. pmd = pmd_offset(pud, addr);
  255. if (pmd_none(*pmd))
  256. goto next;
  257. if (unlikely(pmd_trans_huge(*pmd))) {
  258. has_page = true;
  259. goto next;
  260. }
  261. if (pmd_bad(*pmd))
  262. goto next;
  263. pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
  264. if (pte_none(*pte))
  265. goto next_locked;
  266. /*
  267. if (unlikely(!pte_present(*pte)) && pte_file(*pte))
  268. goto next_locked;
  269. */
  270. has_page = true;
  271. next_locked:
  272. spin_unlock(ptl);
  273. next:
  274. if (has_page) {
  275. DEBUG("found a page at %lx\n", addr);
  276. set_bit(i, page_bit_map);
  277. } else {
  278. clear_bit(i, page_bit_map);
  279. }
  280. } while (i++, addr += PAGE_SIZE, i < nr_pages);
  281. }
  282. static int get_pages (struct task_struct *task, unsigned long start,
  283. unsigned long nr_pages,
  284. unsigned long page_bit_map[PAGE_BITS],
  285. struct page *pages[PAGE_QUEUE],
  286. struct vm_area_struct *vmas[PAGE_QUEUE])
  287. {
  288. struct mm_struct *mm = task->mm;
  289. struct vm_area_struct *vma = NULL;
  290. unsigned long addr = start, nr;
  291. int i = 0, j, rv;
  292. while (i < nr_pages) {
  293. unsigned long flushed, vmflags;
  294. int last = i;
  295. if (test_bit(last, page_bit_map)) {
  296. i = find_next_zero_bit(page_bit_map, PAGE_QUEUE,
  297. last + 1);
  298. if (i > nr_pages)
  299. i = nr_pages;
  300. nr = i - last;
  301. DEBUG("GIPC_SEND get_user_pages %ld pages at %lx\n",
  302. addr, nr);
  303. rv = __get_user_pages(task, mm, addr, nr,
  304. FOLL_GET|FOLL_FORCE|FOLL_SPLIT,
  305. pages + last, vmas + last, NULL);
  306. if (rv <= 0) {
  307. printk(KERN_ERR "Graphene error: "
  308. "get_user_pages at 0x%016lx-0x%016lx\n",
  309. addr, addr + (nr << PAGE_SHIFT));
  310. return rv;
  311. }
  312. if (rv != nr) {
  313. printk(KERN_ERR "Graphene error: "
  314. "get_user_pages at 0x%016lx\n",
  315. addr + (rv << PAGE_SHIFT));
  316. return -EACCES;
  317. }
  318. flushed = addr;
  319. vmflags = 0;
  320. for (j = 0; j < nr; j++) {
  321. unsigned long target = addr + (j << PAGE_SHIFT);
  322. /* Mark source COW */
  323. rv = make_page_cow(mm, vmas[last + j],
  324. target);
  325. if (rv)
  326. return rv;
  327. if (PageAnon(pages[last + j])) {
  328. /* Fix up the counters */
  329. inc_mm_counter_fast(mm, MM_FILEPAGES);
  330. dec_mm_counter_fast(mm, MM_ANONPAGES);
  331. pages[last + j]->mapping = NULL;
  332. }
  333. #ifdef FLUSH_TLB_MM_RANGE
  334. if (vmflags == vmas[last + j]->vm_flags)
  335. continue;
  336. if (flushed < target)
  337. FLUSH_TLB_MM_RANGE(mm, flushed, target,
  338. vmflags);
  339. flushed = target;
  340. vmflags = vmas[last + j]->vm_flags;
  341. #else
  342. FLUSH_TLB_PAGE(vmas[last + j], target);
  343. #endif
  344. }
  345. #ifdef FLUSH_TLB_MM_RANGE
  346. if (flushed < addr + (nr << PAGE_SHIFT))
  347. FLUSH_TLB_MM_RANGE(mm, flushed,
  348. addr + (nr << PAGE_SHIFT),
  349. vmflags);
  350. #endif
  351. vma = vmas[i - 1];
  352. addr += nr << PAGE_SHIFT;
  353. } else {
  354. /* This is the case where a page (or pages) are not
  355. * currently mapped.
  356. * Handle the hole appropriately. */
  357. i = find_next_bit(page_bit_map, PAGE_QUEUE, last + 1);
  358. if (i > nr_pages)
  359. i = nr_pages;
  360. nr = i - last;
  361. DEBUG("GIPC_SEND skip %ld pages at %lx\n", addr, nr);
  362. for (j = 0; j < nr; j++) {
  363. if (!vma) {
  364. vma = find_vma(mm, addr);
  365. } else {
  366. /* DEP 6/17/13 - these addresses should
  367. * be monotonically increasing. */
  368. for (; vma && addr >= vma->vm_end;
  369. vma = vma->vm_next);
  370. /* Leverage monotonic increasing vmas
  371. * to more quickly detect holes in the
  372. * address space. */
  373. if (vma && addr < vma->vm_start)
  374. vma = NULL;
  375. }
  376. pages[last + j] = NULL;
  377. vmas[last + j] = vma;
  378. addr += PAGE_SIZE;
  379. }
  380. }
  381. }
  382. return i;
  383. }
  384. static int do_gipc_send(struct task_struct *task, struct gipc_queue *gq,
  385. struct gipc_send_buffer *gbuf,
  386. unsigned long __user *uaddr, unsigned long __user *ulen,
  387. unsigned long *copied_pages)
  388. {
  389. struct mm_struct *mm = task->mm;
  390. unsigned long addr, len, nr_pages;
  391. int rv, i;
  392. DEBUG("GIPC_SEND uaddr = %p, ulen = %p\n", uaddr, ulen);
  393. rv = copy_from_user(&addr, uaddr, sizeof(unsigned long));
  394. if (rv) {
  395. printk(KERN_ALERT "Graphene SEND: bad buffer %p\n", uaddr);
  396. return -EFAULT;
  397. }
  398. rv = copy_from_user(&len, ulen, sizeof(unsigned long));
  399. if (rv) {
  400. printk(KERN_ALERT "Graphene SEND: bad buffer %p\n", ulen);
  401. return -EFAULT;
  402. }
  403. if (addr > addr + len) {
  404. printk(KERN_ALERT "Graphene SEND: attempt to send %p - %p "
  405. " by thread %d FAIL: bad argument\n",
  406. (void *) addr, (void *) (addr + len), task->pid);
  407. return -EINVAL;
  408. }
  409. DEBUG("GIPC_SEND addr = %lx, len = %ld\n", addr, len);
  410. nr_pages = len >> PAGE_SHIFT;
  411. if (!access_ok(VERIFY_READ, addr, len)) {
  412. printk(KERN_ALERT "Graphene SEND:"
  413. " attempt to send %p - %p (%ld pages) "
  414. " by thread %d FAIL: bad permission\n",
  415. (void *) addr, (void *) (addr + len), nr_pages,
  416. task->pid);
  417. return -EFAULT;
  418. }
  419. DEBUG(" %p - %p (%ld pages) sent by thread %d\n",
  420. (void *) addr, (void *) (addr + len), nr_pages, task->pid);
  421. while (nr_pages) {
  422. unsigned long nr =
  423. (nr_pages <= PAGE_QUEUE) ? nr_pages : PAGE_QUEUE;
  424. /* for each of these addresses - check if
  425. * demand faulting will be triggered
  426. * if vma is present, but there is no page
  427. * present(pmd/pud not present or PTE_PRESENT
  428. * is off) then get_user_pages will trigger
  429. * the creation of those */
  430. down_write(&mm->mmap_sem);
  431. fill_page_bit_map(mm, addr, nr, gbuf->page_bit_map);
  432. rv = get_pages(task, addr, nr,
  433. gbuf->page_bit_map,
  434. gbuf->pages,
  435. gbuf->vmas);
  436. if (rv < 0) {
  437. up_write(&mm->mmap_sem);
  438. break;
  439. }
  440. for (i = 0; i < nr; i++) {
  441. BUG_ON((!gbuf->vmas[i]) && (!!gbuf->pages[i]));
  442. if (gbuf->vmas[i] && gbuf->vmas[i]->vm_file) {
  443. gbuf->files[i] = get_file(gbuf->vmas[i]->vm_file);
  444. gbuf->pgoffs[i] =
  445. ((addr - gbuf->vmas[i]->vm_start) >> PAGE_SHIFT)
  446. + gbuf->vmas[i]->vm_pgoff;
  447. } else {
  448. gbuf->files[i] = NULL;
  449. gbuf->pgoffs[i] = 0;
  450. }
  451. addr += PAGE_SIZE;
  452. }
  453. up_write(&mm->mmap_sem);
  454. for (i = 0; i < nr ; i++) {
  455. /* Put in the pending buffer*/
  456. if (((gq->last + 1) & (PAGE_QUEUE - 1)) == gq->next) {
  457. /* The blocking condition for send
  458. * and recv can't both be true! */
  459. wake_up_all(&gq->recv);
  460. wait_event_interruptible(gq->send,
  461. ((gq->last + 1) & (PAGE_QUEUE - 1)) != gq->next);
  462. if (signal_pending(task)) {
  463. rv = -ERESTARTSYS;
  464. goto out;
  465. }
  466. }
  467. gq->pages[gq->last].page = gbuf->pages[i];
  468. gq->pages[gq->last].file = gbuf->files[i];
  469. gq->pages[gq->last].pgoff = gbuf->pgoffs[i];
  470. gq->last++;
  471. gq->last &= PAGE_QUEUE - 1;
  472. (*copied_pages)++;
  473. }
  474. wake_up_all(&gq->recv);
  475. nr_pages -= nr;
  476. }
  477. out:
  478. return rv;
  479. }
  480. static inline
  481. int recv_next (struct task_struct *task, struct gipc_queue *gq)
  482. {
  483. if (gq->next == gq->last) {
  484. /* The blocking condition for send & recv can't both be true */
  485. wake_up_all(&gq->send);
  486. wait_event_interruptible(gq->recv, gq->next != gq->last);
  487. if (signal_pending(task))
  488. return -ERESTARTSYS;
  489. }
  490. return gq->next;
  491. }
  492. static int do_gipc_recv(struct task_struct *task, struct gipc_queue *gq,
  493. unsigned long __user *uaddr, unsigned long __user *ulen,
  494. unsigned long __user *uprot,
  495. unsigned long *copied_pages)
  496. {
  497. struct mm_struct *mm = task->mm;
  498. struct vm_area_struct *vma = NULL;
  499. unsigned long start, addr, len, nr_pages, prot, pgoff;
  500. struct page *page = NULL;
  501. struct file *file = NULL;
  502. int i = 0, rv;
  503. rv = copy_from_user(&addr, uaddr, sizeof(unsigned long));
  504. if (rv) {
  505. printk(KERN_ALERT "Graphene RECV: bad buffer %p\n", uaddr);
  506. return -EFAULT;
  507. }
  508. rv = copy_from_user(&len, ulen, sizeof(unsigned long));
  509. if (rv) {
  510. printk(KERN_ALERT "Graphene RECV: bad buffer %p\n", ulen);
  511. return -EFAULT;
  512. }
  513. rv = copy_from_user(&prot, uprot, sizeof(unsigned long));
  514. if (rv) {
  515. printk(KERN_ALERT "Graphene RECV: bad buffer %p\n", uprot);
  516. return -EFAULT;
  517. }
  518. nr_pages = len >> PAGE_SHIFT;
  519. start = addr;
  520. down_write(&mm->mmap_sem);
  521. while (i < nr_pages) {
  522. int found = recv_next(task, gq);
  523. int need_map = 1;
  524. if (found < 0) {
  525. rv = found;
  526. goto finish;
  527. }
  528. page = gq->pages[found].page;
  529. file = gq->pages[found].file;
  530. pgoff = gq->pages[found].pgoff;
  531. gq->next++;
  532. gq->next &= PAGE_QUEUE - 1;
  533. wake_up_all(&gq->send);
  534. if (vma) {
  535. need_map = 0;
  536. if (vma->vm_file != file)
  537. need_map = 1;
  538. if (file && vma->vm_start +
  539. ((pgoff - vma->vm_pgoff) << PAGE_SHIFT)
  540. != addr)
  541. need_map = 1;
  542. if (prot != (vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)))
  543. need_map = 1;
  544. }
  545. if (need_map) {
  546. unsigned long flags = MAP_PRIVATE;
  547. if (addr)
  548. flags |= MAP_FIXED;
  549. if (file)
  550. flags |= MAP_FILE;
  551. else
  552. flags |= MAP_ANONYMOUS;
  553. addr = DO_MMAP_PGOFF(file, addr,
  554. (nr_pages - i) << PAGE_SHIFT,
  555. prot, flags, pgoff);
  556. if (IS_ERR_VALUE(addr)) {
  557. rv = PTR_ERR((void *) addr);
  558. printk(KERN_ERR
  559. "Graphene error: failed to mmap (%d)\n",
  560. -rv);
  561. goto finish;
  562. }
  563. if (file)
  564. DEBUG("map %08lx-%08lx file %p\n", addr,
  565. addr + ((nr_pages - i) << PAGE_SHIFT),
  566. file);
  567. else
  568. DEBUG("map %08lx-%08lx\n", addr,
  569. addr + ((nr_pages - i) << PAGE_SHIFT));
  570. if (!start)
  571. start = addr;
  572. vma = find_vma(mm, addr);
  573. if (!vma) {
  574. printk(KERN_ERR
  575. "Graphene error: can't find vma at %p\n",
  576. (void *) addr);
  577. rv = -ENOENT;
  578. goto finish;
  579. }
  580. } else {
  581. BUG_ON(!vma);
  582. }
  583. if (page) {
  584. rv = vm_insert_page(vma, addr, page);
  585. if (rv) {
  586. printk(KERN_ERR "Graphene error: "
  587. "fail to insert page %d\n", rv);
  588. goto finish;
  589. }
  590. rv = make_page_cow(mm, vma, addr);
  591. if (rv) {
  592. printk(KERN_ERR "Graphene error: "
  593. "can't make vma copy-on-write at %p\n",
  594. (void *) addr);
  595. goto finish;
  596. }
  597. }
  598. finish:
  599. /* Drop the kernel's reference to this page */
  600. if (page)
  601. page_cache_release(page);
  602. if (file)
  603. fput_atomic(file);
  604. if (rv)
  605. break;
  606. i++;
  607. addr += PAGE_SIZE;
  608. (*copied_pages)++;
  609. }
  610. up_write(&mm->mmap_sem);
  611. if (i)
  612. DEBUG(" %p - %p (%d pages) received by thread %d\n",
  613. (void *) start, (void *) start + (i << PAGE_SHIFT), i,
  614. task->pid);
  615. if (start) {
  616. rv = copy_to_user(uaddr, &start, sizeof(unsigned long));
  617. if (rv) {
  618. printk(KERN_ERR "Graphene error: bad buffer %p\n",
  619. uaddr);
  620. return -EFAULT;
  621. }
  622. }
  623. return rv;
  624. }
  625. static long gipc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  626. {
  627. struct task_struct *task = current;
  628. struct gipc_queue *gq = NULL;
  629. long rv = 0;
  630. switch (cmd) {
  631. case GIPC_SEND: {
  632. struct gipc_send gs;
  633. struct gipc_send_buffer *gbuf;
  634. int i;
  635. unsigned long nr_pages = 0;
  636. rv = copy_from_user(&gs, (void *) arg, sizeof(gs));
  637. if (rv) {
  638. printk(KERN_ALERT "Graphene SEND: bad buffer %p\n",
  639. (void *) arg);
  640. return -EFAULT;
  641. }
  642. /* Find/allocate the gipc_pages struct for our recipient */
  643. gq = (struct gipc_queue *) file->private_data;
  644. if (!gq)
  645. return -EFAULT;
  646. gbuf = kmem_cache_alloc(gipc_send_buffer_cachep, GFP_KERNEL);
  647. if (!gbuf)
  648. return -ENOMEM;
  649. DEBUG("GIPC_SEND %ld entries to token %lld by thread %d\n",
  650. gs.entries, gq->token, task->pid);
  651. mutex_lock(&gq->send_lock);
  652. for (i = 0; i < gs.entries; i++) {
  653. rv = do_gipc_send(task, gq, gbuf, gs.addr + i,
  654. gs.len + i, &nr_pages);
  655. if (rv < 0)
  656. break;
  657. }
  658. mutex_unlock(&gq->send_lock);
  659. DEBUG("GIPC_SEND return to thread %d, %ld pages are sent\n",
  660. task->pid, nr_pages);
  661. kmem_cache_free(gipc_send_buffer_cachep, gbuf);
  662. rv = nr_pages ? : rv;
  663. break;
  664. }
  665. case GIPC_RECV: {
  666. struct gipc_recv gr;
  667. int i;
  668. unsigned long nr_pages = 0;
  669. rv = copy_from_user(&gr, (void *) arg, sizeof(gr));
  670. if (rv) {
  671. printk(KERN_ERR "Graphene error: bad buffer %p\n",
  672. (void *) arg);
  673. return -EFAULT;
  674. }
  675. gq = (struct gipc_queue *) file->private_data;
  676. if (!gq)
  677. return -EBADF;
  678. DEBUG("GIPC_RECV %ld entries to token %lld by thread %d\n",
  679. gr.entries, gq->token, task->pid);
  680. mutex_lock(&gq->recv_lock);
  681. for (i = 0; i < gr.entries; i++) {
  682. rv = do_gipc_recv(task, gq, gr.addr + i, gr.len + i,
  683. gr.prot + i, &nr_pages);
  684. if (rv < 0)
  685. break;
  686. }
  687. mutex_unlock(&gq->recv_lock);
  688. DEBUG("GIPC_RECV return to thread %d, %ld pages are received\n",
  689. task->pid, nr_pages);
  690. rv = nr_pages ? : rv;
  691. break;
  692. }
  693. case GIPC_CREATE: {
  694. gq = create_gipc_queue(file);
  695. if (!gq) {
  696. rv = -ENOMEM;
  697. break;
  698. }
  699. DEBUG("GIPC_CREATE token %lld by thread %d\n", gq->token,
  700. task->pid);
  701. rv = gq->token;
  702. break;
  703. }
  704. case GIPC_JOIN: {
  705. struct gipc_queue *q;
  706. u64 token = arg;
  707. u64 session = GIPC_OWNER;
  708. if (file->private_data != NULL)
  709. return -EBUSY;
  710. /* Search for this token */
  711. spin_lock(&gdev.lock);
  712. list_for_each_entry(q, &gdev.channels, list) {
  713. if (q->token == token) {
  714. gq = q;
  715. break;
  716. }
  717. }
  718. /* Fail if we didn't find it */
  719. if (!gq) {
  720. spin_unlock(&gdev.lock);
  721. return -ENOENT;
  722. }
  723. if (gq->owner != session) {
  724. spin_unlock(&gdev.lock);
  725. return -EPERM;
  726. }
  727. atomic_inc(&gq->count);
  728. file->private_data = gq;
  729. /* Hold the lock until we allocate so only one process
  730. * gets the queue */
  731. spin_unlock(&gdev.lock);
  732. DEBUG("GIPC_JOIN token %lld by thread %d\n", token, task->pid);
  733. rv = 0;
  734. break;
  735. }
  736. default:
  737. printk(KERN_ALERT "Graphene unknown ioctl %u %lu\n", cmd, arg);
  738. rv = -ENOSYS;
  739. break;
  740. }
  741. return rv;
  742. }
  743. static int gipc_release(struct inode *inode, struct file *file)
  744. {
  745. struct gipc_queue *gq = (struct gipc_queue *) file->private_data;
  746. if (!gq)
  747. return 0;
  748. file->private_data = NULL;
  749. release_gipc_queue(gq, false);
  750. return 0;
  751. }
  752. static int gipc_open(struct inode *inode, struct file *file)
  753. {
  754. file->private_data = NULL;
  755. return 0;
  756. }
  757. static struct file_operations gipc_fops = {
  758. .owner = THIS_MODULE,
  759. .release = gipc_release,
  760. .open = gipc_open,
  761. .unlocked_ioctl = gipc_ioctl,
  762. .compat_ioctl = gipc_ioctl,
  763. .llseek = noop_llseek,
  764. };
  765. static struct miscdevice gipc_dev = {
  766. .minor = GIPC_MINOR,
  767. .name = "gipc",
  768. .fops = &gipc_fops,
  769. .mode = 0666,
  770. };
  771. static int __init gipc_init(void)
  772. {
  773. int rv = 0;
  774. #ifdef MY_DO_MMAP_PGOFF
  775. LOOKUP_KALLSYMS(do_mmap_pgoff);
  776. #endif
  777. #ifdef MY_FLUSH_TLB_MM_RANGE
  778. LOOKUP_KALLSYMS(flush_tlb_mm_range);
  779. #endif
  780. #ifdef MY_FLUSH_TLB_PAGE
  781. LOOKUP_KALLSYMS(flush_tlb_page);
  782. #endif
  783. #ifndef gipc_get_session
  784. my_gipc_get_session = (void *) kallsyms_lookup_name("gipc_get_session");
  785. #endif
  786. /* Register the kmem cache */
  787. gipc_queue_cachep = kmem_cache_create("gipc queue",
  788. sizeof(struct gipc_queue),
  789. 0,
  790. SLAB_HWCACHE_ALIGN|
  791. SLAB_DESTROY_BY_RCU,
  792. NULL);
  793. if (!gipc_queue_cachep) {
  794. printk(KERN_ERR "Graphene error: "
  795. "failed to create a gipc queues cache\n");
  796. return -ENOMEM;
  797. }
  798. gipc_send_buffer_cachep = kmem_cache_create("gipc send buffer",
  799. sizeof(struct gipc_send_buffer),
  800. 0,
  801. SLAB_HWCACHE_ALIGN|
  802. SLAB_DESTROY_BY_RCU,
  803. NULL);
  804. if (!gipc_send_buffer_cachep) {
  805. printk(KERN_ERR "Graphene error: "
  806. "failed to create a gipc buffers cache\n");
  807. return -ENOMEM;
  808. }
  809. INIT_LIST_HEAD(&gdev.channels);
  810. spin_lock_init(&gdev.lock);
  811. gdev.max_token = 1;
  812. rv = misc_register(&gipc_dev);
  813. if (rv) {
  814. printk(KERN_ERR "Graphene error: "
  815. "failed to add a char device (rv=%d)\n", rv);
  816. return rv;
  817. }
  818. printk(KERN_ALERT "Graphene IPC: Hello, world\n");
  819. return 0;
  820. }
  821. static void __exit gipc_exit(void)
  822. {
  823. struct gipc_queue *gq, *n;
  824. spin_lock(&gdev.lock);
  825. list_for_each_entry_safe(gq, n, &gdev.channels, list)
  826. release_gipc_queue(gq, true);
  827. spin_unlock(&gdev.lock);
  828. misc_deregister(&gipc_dev);
  829. kmem_cache_destroy(gipc_queue_cachep);
  830. printk(KERN_ALERT "Graphene IPC: Goodbye, cruel world\n");
  831. }
  832. module_init(gipc_init);
  833. module_exit(gipc_exit);