Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
630986cd
Commit
630986cd
authored
Aug 12, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Automerge
parents
7366f03f
d24919a7
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
335 additions
and
154 deletions
+335
-154
arch/i386/mm/ioremap.c
arch/i386/mm/ioremap.c
+3
-3
arch/sparc64/mm/modutil.c
arch/sparc64/mm/modutil.c
+48
-7
drivers/char/mem.c
drivers/char/mem.c
+3
-2
include/linux/vmalloc.h
include/linux/vmalloc.h
+30
-27
kernel/ksyms.c
kernel/ksyms.c
+2
-0
mm/vmalloc.c
mm/vmalloc.c
+249
-115
No files found.
arch/i386/mm/ioremap.c
View file @
630986cd
...
...
@@ -159,7 +159,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
area
->
phys_addr
=
phys_addr
;
addr
=
area
->
addr
;
if
(
remap_area_pages
(
VMALLOC_VMADDR
(
addr
),
phys_addr
,
size
,
flags
))
{
v
free
(
addr
);
v
unmap
(
addr
);
return
NULL
;
}
return
(
void
*
)
(
offset
+
(
char
*
)
addr
);
...
...
@@ -215,13 +215,13 @@ void iounmap(void *addr)
struct
vm_struct
*
p
;
if
(
addr
<=
high_memory
)
return
;
p
=
remove_
kernel
_area
((
void
*
)
(
PAGE_MASK
&
(
unsigned
long
)
addr
));
p
=
remove_
vm
_area
((
void
*
)
(
PAGE_MASK
&
(
unsigned
long
)
addr
));
if
(
!
p
)
{
printk
(
"__iounmap: bad address %p
\n
"
,
addr
);
return
;
}
vmfree_area_pages
(
VMALLOC_VMADDR
(
p
->
addr
),
p
->
size
);
unmap_vm_area
(
p
);
if
(
p
->
flags
&&
p
->
phys_addr
<
virt_to_phys
(
high_memory
))
{
change_page_attr
(
virt_to_page
(
__va
(
p
->
phys_addr
)),
p
->
size
>>
PAGE_SHIFT
,
...
...
arch/sparc64/mm/modutil.c
View file @
630986cd
...
...
@@ -5,6 +5,8 @@
* Based upon code written by Linus Torvalds and others.
*/
#warning "major untested changes to this file --hch (2002/08/05)"
#include <linux/slab.h>
#include <linux/vmalloc.h>
...
...
@@ -16,6 +18,7 @@ static struct vm_struct * modvmlist = NULL;
void
module_unmap
(
void
*
addr
)
{
struct
vm_struct
**
p
,
*
tmp
;
int
i
;
if
(
!
addr
)
return
;
...
...
@@ -23,21 +26,38 @@ void module_unmap (void * addr)
printk
(
"Trying to unmap module with bad address (%p)
\n
"
,
addr
);
return
;
}
for
(
p
=
&
modvmlist
;
(
tmp
=
*
p
)
;
p
=
&
tmp
->
next
)
{
if
(
tmp
->
addr
==
addr
)
{
*
p
=
tmp
->
next
;
vmfree_area_pages
(
VMALLOC_VMADDR
(
tmp
->
addr
),
tmp
->
size
);
kfree
(
tmp
);
return
;
}
}
printk
(
"Trying to unmap nonexistent module vm area (%p)
\n
"
,
addr
);
return
;
found:
unmap_vm_area
(
tmp
);
for
(
i
=
0
;
i
<
tmp
->
nr_pages
;
i
++
)
{
if
(
unlikely
(
!
tmp
->
pages
[
i
]))
BUG
();
__free_page
(
tmp
->
pages
[
i
]);
}
kfree
(
tmp
->
pages
);
kfree
(
tmp
);
}
void
*
module_map
(
unsigned
long
size
)
{
void
*
addr
;
struct
vm_struct
**
p
,
*
tmp
,
*
area
;
struct
vm_struct
*
area
;
struct
page
**
pages
;
void
*
addr
;
unsigned
int
nr_pages
,
array_size
,
i
;
size
=
PAGE_ALIGN
(
size
);
if
(
!
size
||
size
>
MODULES_LEN
)
return
NULL
;
...
...
@@ -55,11 +75,32 @@ void * module_map (unsigned long size)
area
->
size
=
size
+
PAGE_SIZE
;
area
->
addr
=
addr
;
area
->
next
=
*
p
;
area
->
pages
=
NULL
;
area
->
nr_pages
=
0
;
area
->
phys_addr
=
0
;
*
p
=
area
;
if
(
vmalloc_area_pages
(
VMALLOC_VMADDR
(
addr
),
size
,
GFP_KERNEL
,
PAGE_KERNEL
))
{
module_unmap
(
addr
);
nr_pages
=
(
size
+
PAGE_SIZE
)
>>
PAGE_SHIFT
;
array_size
=
(
nr_pages
*
sizeof
(
struct
page
*
));
area
->
nr_pages
=
nr_pages
;
area
->
pages
=
pages
=
kmalloc
(
array_size
,
(
gfp_mask
&
~
__GFP_HIGHMEM
));
if
(
!
area
->
pages
)
return
NULL
;
memset
(
area
->
pages
,
0
,
array_size
);
for
(
i
=
0
;
i
<
area
->
nr_pages
;
i
++
)
{
area
->
pages
[
i
]
=
alloc_page
(
gfp_mask
);
if
(
unlikely
(
!
area
->
pages
[
i
]))
goto
fail
;
}
return
addr
;
if
(
map_vm_area
(
area
,
prot
,
&
pages
))
goto
fail
;
return
area
->
addr
;
fail:
vfree
(
area
->
addr
);
return
NULL
;
}
}
drivers/char/mem.c
View file @
630986cd
...
...
@@ -210,6 +210,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
return
0
;
}
extern
long
vread
(
char
*
buf
,
char
*
addr
,
unsigned
long
count
);
extern
long
vwrite
(
char
*
buf
,
char
*
addr
,
unsigned
long
count
);
/*
* This function reads the *virtual* memory as seen by the kernel.
*/
...
...
@@ -273,8 +276,6 @@ static ssize_t read_kmem(struct file *file, char *buf,
return
virtr
+
read
;
}
extern
long
vwrite
(
char
*
buf
,
char
*
addr
,
unsigned
long
count
);
/*
* This function writes to the *virtual* memory as seen by the kernel.
*/
...
...
include/linux/vmalloc.h
View file @
630986cd
#ifndef _
_
LINUX_VMALLOC_H
#define _
_
LINUX_VMALLOC_H
#ifndef _LINUX_VMALLOC_H
#define _LINUX_VMALLOC_H
#include <linux/spinlock.h>
#include <asm/pgtable.h>
/* bits in vm_struct->flags */
#define VM_IOREMAP 0x00000001
/* ioremap() and friends */
#define VM_ALLOC 0x00000002
/* vmalloc() */
#define VM_MAP 0x00000004
/* vmap()ed pages */
struct
vm_struct
{
unsigned
long
flags
;
void
*
addr
;
void
*
addr
;
unsigned
long
size
;
unsigned
long
flags
;
struct
page
**
pages
;
unsigned
int
nr_pages
;
unsigned
long
phys_addr
;
struct
vm_struct
*
next
;
struct
vm_struct
*
next
;
};
extern
struct
vm_struct
*
get_vm_area
(
unsigned
long
size
,
unsigned
long
flags
);
extern
void
vfree
(
void
*
addr
);
extern
void
*
__vmalloc
(
unsigned
long
size
,
int
gfp_mask
,
pgprot_t
prot
);
extern
long
vread
(
char
*
buf
,
char
*
addr
,
unsigned
long
count
);
extern
void
vmfree_area_pages
(
unsigned
long
address
,
unsigned
long
size
);
extern
int
vmalloc_area_pages
(
unsigned
long
address
,
unsigned
long
size
,
int
gfp_mask
,
pgprot_t
prot
);
extern
struct
vm_struct
*
remove_kernel_area
(
void
*
addr
);
/*
*
Various ways to allocate pages.
*
Highlevel APIs for driver use
*/
extern
void
*
vmalloc
(
unsigned
long
size
);
extern
void
*
vmalloc_32
(
unsigned
long
size
);
extern
void
*
__vmalloc
(
unsigned
long
size
,
int
gfp_mask
,
pgprot_t
prot
);
extern
void
vfree
(
void
*
addr
);
extern
void
*
vmalloc
(
unsigned
long
size
);
extern
void
*
vmalloc_32
(
unsigned
long
size
);
extern
void
*
vmap
(
struct
page
**
pages
,
unsigned
int
count
);
extern
void
vunmap
(
void
*
addr
);
/*
* vmlist_lock is a read-write spinlock that protects vmlist
* Used in mm/vmalloc.c (get_vm_area() and vfree()) and fs/proc/kcore.c.
* Lowlevel-APIs (not for driver use!)
*/
extern
rwlock_t
vmlist_lock
;
extern
struct
vm_struct
*
get_vm_area
(
unsigned
long
size
,
unsigned
long
flags
);
extern
struct
vm_struct
*
remove_vm_area
(
void
*
addr
);
extern
int
map_vm_area
(
struct
vm_struct
*
area
,
pgprot_t
prot
,
struct
page
***
pages
);
extern
void
unmap_vm_area
(
struct
vm_struct
*
area
);
extern
struct
vm_struct
*
vmlist
;
#endif
/*
* Internals. Dont't use..
*/
extern
rwlock_t
vmlist_lock
;
extern
struct
vm_struct
*
vmlist
;
#endif
/* _LINUX_VMALLOC_H */
kernel/ksyms.c
View file @
630986cd
...
...
@@ -109,6 +109,8 @@ EXPORT_SYMBOL(vfree);
EXPORT_SYMBOL
(
__vmalloc
);
EXPORT_SYMBOL
(
vmalloc
);
EXPORT_SYMBOL
(
vmalloc_32
);
EXPORT_SYMBOL
(
vmap
);
EXPORT_SYMBOL
(
vunmap
);
EXPORT_SYMBOL
(
vmalloc_to_page
);
EXPORT_SYMBOL
(
mem_map
);
EXPORT_SYMBOL
(
remap_page_range
);
...
...
mm/vmalloc.c
View file @
630986cd
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment