linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: "陳韋任 (Wei-Ren Chen)" <chenwj@iis.sinica.edu.tw>
To: linux-mm@kvack.org
Subject: What else need to be done if we allocate phys page manually?
Date: Tue, 11 Sep 2012 19:09:39 +0800	[thread overview]
Message-ID: <20120911110939.GA49608@cs.nctu.edu.tw> (raw)

[-- Attachment #1: Type: text/plain, Size: 2261 bytes --]

Hi all,

  Please let me explain what I am trying to do first. First, I compile
a 64 bit binary so that it'll be loaded above 4G virtual space, so the
virtual space below 4G is empty. I want to make a virtual address below
4G share the same phys page with another virtual address above 4G, so
that read/write vadd1 just like vaddr2. 


               PGD/PUD/PMD       Page Table
                                 ----------             Phys Page 2
                                |          |             --------
                                |----------|            |        |
                     vaddr2     |   pte 2  | ---------> |        |
                                |----------|            |        |
                                |          |             --------
                                |          |                ^
  4G above                      |          |                |
 ---------------------------------------------              |
                                |          |                |
                                |          |                |
                                |----------|                |
                     vaddr1     |   pte 1  | ---------------
                                |----------|            
                                |          |            
                                |__________|


Currently, I choose to manually create PUD/PMD/PT associated with vaddr1
, and set pte1 to point to phys page 2 (you can see the attach example
syscall, vadd1 is fixed to 0x10000000 for simplicity). However, the page
I create for PMD in the example will cause memory leak (see below). What
is the proper way to do so that kernel can free the page I allocated
automatically when the application calling the syscall is terminated?

    pmd = pmd_offset(pud, vaddr);
    if(pmd_none(*pmd)) {
        page = pte_alloc_one(current->mm, vaddr);
        pmd_n = mk_pmd(page, pgprot);
        set_pmd(pmd, pmd_n);
    }
 
  Thanks!

Regards,
chenwj

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj

[-- Attachment #2: syscall.c --]
[-- Type: text/x-csrc, Size: 1865 bytes --]

#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/sched.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>

// vaddr_h: vaddr above 4G
long sys_set_pte(unsigned long vaddr_h)
{
    unsigned long vaddr = 0x10000000 | (vaddr_h & 0xfff); // make vaddr's pte point to vaddr_h's phys page
    // vaddr and vaddr_h shares the same pgd and pud, need to creat pmd and page table
    pgd_t *pgd;
    pud_t *pud;
    pmd_t *pmd, pmd_n; // pmd_n is for vaddr
    pte_t *pte, *pte_h;
    struct page *page;
    pgprot_t pgprot;
    
    // get vaddr_h's physical page
    pgd = pgd_offset(current->mm, vaddr_h);
    pud = pud_offset(pgd, vaddr_h);
    pmd = pmd_offset(pud, vaddr_h);
    pgprot = __pgprot(pmd_val(*pmd) & 0xfff); // we copy vaddr_h's pmd permission to vaddr's pmd
    pte_h = pte_offset_map(pmd, vaddr_h);
    
    // mapping vaddr_h above 4G to vaddr below 4G alloc page entry
    pgd = pgd_offset(current->mm, vaddr);
    if (pgd_none(*pgd)) {
        printk("pgd entry not found, alloc new pud and set pgd entry\n");
        pgd = pgd_alloc(current->mm);
    }

    pud = pud_offset(pgd, vaddr);
    if(pud_none(*pud)) {
        printk("pud entry not found, alloc new pmd and set pud entry\n");
        pud = pud_alloc(current->mm, pgd, vaddr);
    }
    
    pmd = pmd_offset(pud, vaddr);
    if(pmd_none(*pmd)) {
        printk("pmd entry not found, alloc new pte and set pmd entry\n");
        page = pte_alloc_one(current->mm, vaddr); // allocate pte, i.e., page table
        pmd_n = mk_pmd(page, pgprot); // make a new pmd entry which ponits to page with pgprot permission
        set_pmd(pmd, pmd_n); // replace old pmd entry (pmd) with a new one (pmd_n)
    }

    // pte = page table entry
    pte = pte_offset_map(pmd, vaddr);

    // replace vaddr page table entry (pte) with vaddr_h's one (*pte_h)
    set_pte(pte, *pte_h);
}

                 reply	other threads:[~2012-09-11 11:10 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120911110939.GA49608@cs.nctu.edu.tw \
    --to=chenwj@iis.sinica.edu.tw \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox