lkml.org 
[lkml]   [2009]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/6] ksm: dont allow overlap memory addresses registrations.
    Date
    subjects say it all.

    Signed-off-by: Izik Eidus <ieidus@redhat.com>
    ---
    mm/ksm.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
    1 files changed, 54 insertions(+), 4 deletions(-)

    diff --git a/mm/ksm.c b/mm/ksm.c
    index d58db6b..982dfff 100644
    --- a/mm/ksm.c
    +++ b/mm/ksm.c
    @@ -451,21 +451,71 @@ static void remove_page_from_tree(struct mm_struct *mm,
    remove_rmap_item_from_tree(rmap_item);
    }

    +static inline int is_intersecting_address(unsigned long addr,
    + unsigned long begin,
    + unsigned long end)
    +{
    + if (addr >= begin && addr < end)
    + return 1;
    + return 0;
    +}
    +
    +/*
    + * is_overlap_mem - check if there is overlapping with memory that was already
    + * registred.
    + *
    + * note - this function must to be called under slots_lock
    + */
    +static int is_overlap_mem(struct ksm_memory_region *mem)
    +{
    + struct ksm_mem_slot *slot;
    +
    + list_for_each_entry(slot, &slots, link) {
    + unsigned long mem_end;
    + unsigned long slot_end;
    +
    + cond_resched();
    +
    + if (current->mm != slot->mm)
    + continue;
    +
    + mem_end = mem->addr + (unsigned long)mem->npages * PAGE_SIZE;
    + slot_end = slot->addr + (unsigned long)slot->npages * PAGE_SIZE;
    +
    + if (is_intersecting_address(mem->addr, slot->addr, slot_end) ||
    + is_intersecting_address(mem_end - 1, slot->addr, slot_end))
    + return 1;
    + if (is_intersecting_address(slot->addr, mem->addr, mem_end) ||
    + is_intersecting_address(slot_end - 1, mem->addr, mem_end))
    + return 1;
    + }
    +
    + return 0;
    +}
    +
    static int ksm_sma_ioctl_register_memory_region(struct ksm_sma *ksm_sma,
    struct ksm_memory_region *mem)
    {
    struct ksm_mem_slot *slot;
    int ret = -EPERM;

    + if (!mem->npages)
    + goto out;
    +
    + down_write(&slots_lock);
    +
    if ((ksm_sma->nregions + 1) > regions_per_fd) {
    ret = -EBUSY;
    - goto out;
    + goto out_unlock;
    }

    + if (is_overlap_mem(mem))
    + goto out_unlock;
    +
    slot = kzalloc(sizeof(struct ksm_mem_slot), GFP_KERNEL);
    if (!slot) {
    ret = -ENOMEM;
    - goto out;
    + goto out_unlock;
    }

    /*
    @@ -478,8 +528,6 @@ static int ksm_sma_ioctl_register_memory_region(struct ksm_sma *ksm_sma,
    slot->addr = mem->addr;
    slot->npages = mem->npages;

    - down_write(&slots_lock);
    -
    list_add_tail(&slot->link, &slots);
    list_add_tail(&slot->sma_link, &ksm_sma->sma_slots);
    ksm_sma->nregions++;
    @@ -489,6 +537,8 @@ static int ksm_sma_ioctl_register_memory_region(struct ksm_sma *ksm_sma,

    out_free:
    kfree(slot);
    +out_unlock:
    + up_write(&slots_lock);
    out:
    return ret;
    }
    --
    1.5.6.5


    \
     
     \ /
      Last update: 2009-05-05 00:31    [W:3.180 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site