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
Kirill Smelkov
linux
Commits
f1d04b23
Commit
f1d04b23
authored
Dec 15, 2014
by
David Vrabel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'devel/for-linus-3.19' into stable/for-linus-3.19
parents
4ef8e3f3
cdfa0bad
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
779 additions
and
965 deletions
+779
-965
arch/x86/include/asm/pgtable_types.h
arch/x86/include/asm/pgtable_types.h
+1
-0
arch/x86/include/asm/xen/page.h
arch/x86/include/asm/xen/page.h
+50
-14
arch/x86/mm/pageattr.c
arch/x86/mm/pageattr.c
+20
-0
arch/x86/xen/mmu.c
arch/x86/xen/mmu.c
+26
-14
arch/x86/xen/p2m.c
arch/x86/xen/p2m.c
+451
-721
arch/x86/xen/setup.c
arch/x86/xen/setup.c
+227
-214
arch/x86/xen/xen-ops.h
arch/x86/xen/xen-ops.h
+4
-2
No files found.
arch/x86/include/asm/pgtable_types.h
View file @
f1d04b23
...
...
@@ -396,6 +396,7 @@ static inline void update_page_count(int level, unsigned long pages) { }
extern
pte_t
*
lookup_address
(
unsigned
long
address
,
unsigned
int
*
level
);
extern
pte_t
*
lookup_address_in_pgd
(
pgd_t
*
pgd
,
unsigned
long
address
,
unsigned
int
*
level
);
extern
pmd_t
*
lookup_pmd_address
(
unsigned
long
address
);
extern
phys_addr_t
slow_virt_to_phys
(
void
*
__address
);
extern
int
kernel_map_pages_in_pgd
(
pgd_t
*
pgd
,
u64
pfn
,
unsigned
long
address
,
unsigned
numpages
,
unsigned
long
page_flags
);
...
...
arch/x86/include/asm/xen/page.h
View file @
f1d04b23
...
...
@@ -41,10 +41,12 @@ typedef struct xpaddr {
extern
unsigned
long
*
machine_to_phys_mapping
;
extern
unsigned
long
machine_to_phys_nr
;
extern
unsigned
long
*
xen_p2m_addr
;
extern
unsigned
long
xen_p2m_size
;
extern
unsigned
long
xen_max_p2m_pfn
;
extern
unsigned
long
get_phys_to_machine
(
unsigned
long
pfn
);
extern
bool
set_phys_to_machine
(
unsigned
long
pfn
,
unsigned
long
mfn
);
extern
bool
__init
early_set_phys_to_machine
(
unsigned
long
pfn
,
unsigned
long
mfn
);
extern
bool
__set_phys_to_machine
(
unsigned
long
pfn
,
unsigned
long
mfn
);
extern
unsigned
long
set_phys_range_identity
(
unsigned
long
pfn_s
,
unsigned
long
pfn_e
);
...
...
@@ -52,17 +54,52 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s,
extern
int
set_foreign_p2m_mapping
(
struct
gnttab_map_grant_ref
*
map_ops
,
struct
gnttab_map_grant_ref
*
kmap_ops
,
struct
page
**
pages
,
unsigned
int
count
);
extern
int
m2p_add_override
(
unsigned
long
mfn
,
struct
page
*
page
,
struct
gnttab_map_grant_ref
*
kmap_op
);
extern
int
clear_foreign_p2m_mapping
(
struct
gnttab_unmap_grant_ref
*
unmap_ops
,
struct
gnttab_map_grant_ref
*
kmap_ops
,
struct
page
**
pages
,
unsigned
int
count
);
extern
int
m2p_remove_override
(
struct
page
*
page
,
struct
gnttab_map_grant_ref
*
kmap_op
,
unsigned
long
mfn
);
extern
struct
page
*
m2p_find_override
(
unsigned
long
mfn
);
extern
unsigned
long
m2p_find_override_pfn
(
unsigned
long
mfn
,
unsigned
long
pfn
);
/*
* Helper functions to write or read unsigned long values to/from
* memory, when the access may fault.
*/
static
inline
int
xen_safe_write_ulong
(
unsigned
long
*
addr
,
unsigned
long
val
)
{
return
__put_user
(
val
,
(
unsigned
long
__user
*
)
addr
);
}
static
inline
int
xen_safe_read_ulong
(
unsigned
long
*
addr
,
unsigned
long
*
val
)
{
return
__get_user
(
*
val
,
(
unsigned
long
__user
*
)
addr
);
}
/*
* When to use pfn_to_mfn(), __pfn_to_mfn() or get_phys_to_machine():
* - pfn_to_mfn() returns either INVALID_P2M_ENTRY or the mfn. No indicator
* bits (identity or foreign) are set.
* - __pfn_to_mfn() returns the found entry of the p2m table. A possibly set
* identity or foreign indicator will be still set. __pfn_to_mfn() is
* encapsulating get_phys_to_machine() which is called in special cases only.
* - get_phys_to_machine() is to be called by __pfn_to_mfn() only in special
* cases needing an extended handling.
*/
static
inline
unsigned
long
__pfn_to_mfn
(
unsigned
long
pfn
)
{
unsigned
long
mfn
;
if
(
pfn
<
xen_p2m_size
)
mfn
=
xen_p2m_addr
[
pfn
];
else
if
(
unlikely
(
pfn
<
xen_max_p2m_pfn
))
return
get_phys_to_machine
(
pfn
);
else
return
IDENTITY_FRAME
(
pfn
);
if
(
unlikely
(
mfn
==
INVALID_P2M_ENTRY
))
return
get_phys_to_machine
(
pfn
);
return
mfn
;
}
static
inline
unsigned
long
pfn_to_mfn
(
unsigned
long
pfn
)
{
unsigned
long
mfn
;
...
...
@@ -70,7 +107,7 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
if
(
xen_feature
(
XENFEAT_auto_translated_physmap
))
return
pfn
;
mfn
=
get_phys_to_machine
(
pfn
);
mfn
=
__pfn_to_mfn
(
pfn
);
if
(
mfn
!=
INVALID_P2M_ENTRY
)
mfn
&=
~
(
FOREIGN_FRAME_BIT
|
IDENTITY_FRAME_BIT
);
...
...
@@ -83,7 +120,7 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
if
(
xen_feature
(
XENFEAT_auto_translated_physmap
))
return
1
;
return
get_phys_to_machine
(
pfn
)
!=
INVALID_P2M_ENTRY
;
return
__pfn_to_mfn
(
pfn
)
!=
INVALID_P2M_ENTRY
;
}
static
inline
unsigned
long
mfn_to_pfn_no_overrides
(
unsigned
long
mfn
)
...
...
@@ -102,7 +139,7 @@ static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
* In such cases it doesn't matter what we return (we return garbage),
* but we must handle the fault without crashing!
*/
ret
=
__get_user
(
pfn
,
&
machine_to_phys_mapping
[
mfn
]
);
ret
=
xen_safe_read_ulong
(
&
machine_to_phys_mapping
[
mfn
],
&
pfn
);
if
(
ret
<
0
)
return
~
0
;
...
...
@@ -117,7 +154,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
return
mfn
;
pfn
=
mfn_to_pfn_no_overrides
(
mfn
);
if
(
get_phys_to_machine
(
pfn
)
!=
mfn
)
{
if
(
__pfn_to_mfn
(
pfn
)
!=
mfn
)
{
/*
* If this appears to be a foreign mfn (because the pfn
* doesn't map back to the mfn), then check the local override
...
...
@@ -133,8 +170,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
* entry doesn't map back to the mfn and m2p_override doesn't have a
* valid entry for it.
*/
if
(
pfn
==
~
0
&&
get_phys_to_machine
(
mfn
)
==
IDENTITY_FRAME
(
mfn
))
if
(
pfn
==
~
0
&&
__pfn_to_mfn
(
mfn
)
==
IDENTITY_FRAME
(
mfn
))
pfn
=
mfn
;
return
pfn
;
...
...
@@ -180,7 +216,7 @@ static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
return
mfn
;
pfn
=
mfn_to_pfn
(
mfn
);
if
(
get_phys_to_machine
(
pfn
)
!=
mfn
)
if
(
__pfn_to_mfn
(
pfn
)
!=
mfn
)
return
-
1
;
/* force !pfn_valid() */
return
pfn
;
}
...
...
arch/x86/mm/pageattr.c
View file @
f1d04b23
...
...
@@ -383,6 +383,26 @@ static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address,
return
lookup_address
(
address
,
level
);
}
/*
* Lookup the PMD entry for a virtual address. Return a pointer to the entry
* or NULL if not present.
*/
pmd_t
*
lookup_pmd_address
(
unsigned
long
address
)
{
pgd_t
*
pgd
;
pud_t
*
pud
;
pgd
=
pgd_offset_k
(
address
);
if
(
pgd_none
(
*
pgd
))
return
NULL
;
pud
=
pud_offset
(
pgd
,
address
);
if
(
pud_none
(
*
pud
)
||
pud_large
(
*
pud
)
||
!
pud_present
(
*
pud
))
return
NULL
;
return
pmd_offset
(
pud
,
address
);
}
/*
* This is necessary because __pa() does not work on some
* kinds of memory, like vmalloc() or the alloc_remap()
...
...
arch/x86/xen/mmu.c
View file @
f1d04b23
...
...
@@ -387,7 +387,7 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
unsigned
long
mfn
;
if
(
!
xen_feature
(
XENFEAT_auto_translated_physmap
))
mfn
=
get_phys_to_machine
(
pfn
);
mfn
=
__pfn_to_mfn
(
pfn
);
else
mfn
=
pfn
;
/*
...
...
@@ -1158,20 +1158,16 @@ static void __init xen_cleanhighmap(unsigned long vaddr,
* instead of somewhere later and be confusing. */
xen_mc_flush
();
}
static
void
__init
xen_pagetable_p2m_copy
(
void
)
static
void
__init
xen_pagetable_p2m_free
(
void
)
{
unsigned
long
size
;
unsigned
long
addr
;
unsigned
long
new_mfn_list
;
if
(
xen_feature
(
XENFEAT_auto_translated_physmap
))
return
;
size
=
PAGE_ALIGN
(
xen_start_info
->
nr_pages
*
sizeof
(
unsigned
long
));
new_mfn_list
=
xen_revector_p2m_tree
();
/* No memory or already called. */
if
(
!
new_mfn_list
||
new_mfn_list
==
xen_start_info
->
mfn_list
)
if
(
(
unsigned
long
)
xen_p2m_addr
==
xen_start_info
->
mfn_list
)
return
;
/* using __ka address and sticking INVALID_P2M_ENTRY! */
...
...
@@ -1189,8 +1185,6 @@ static void __init xen_pagetable_p2m_copy(void)
size
=
PAGE_ALIGN
(
xen_start_info
->
nr_pages
*
sizeof
(
unsigned
long
));
memblock_free
(
__pa
(
xen_start_info
->
mfn_list
),
size
);
/* And revector! Bye bye old array */
xen_start_info
->
mfn_list
=
new_mfn_list
;
/* At this stage, cleanup_highmap has already cleaned __ka space
* from _brk_limit way up to the max_pfn_mapped (which is the end of
...
...
@@ -1214,17 +1208,35 @@ static void __init xen_pagetable_p2m_copy(void)
}
#endif
static
void
__init
xen_pagetable_
init
(
void
)
static
void
__init
xen_pagetable_
p2m_setup
(
void
)
{
paging_init
();
if
(
xen_feature
(
XENFEAT_auto_translated_physmap
))
return
;
xen_vmalloc_p2m_tree
();
#ifdef CONFIG_X86_64
xen_pagetable_p2m_
copy
();
xen_pagetable_p2m_
free
();
#endif
/* And revector! Bye bye old array */
xen_start_info
->
mfn_list
=
(
unsigned
long
)
xen_p2m_addr
;
}
static
void
__init
xen_pagetable_init
(
void
)
{
paging_init
();
xen_post_allocator_init
();
xen_pagetable_p2m_setup
();
/* Allocate and initialize top and mid mfn levels for p2m structure */
xen_build_mfn_list_list
();
/* Remap memory freed due to conflicts with E820 map */
if
(
!
xen_feature
(
XENFEAT_auto_translated_physmap
))
xen_remap_memory
();
xen_setup_shared_info
();
xen_post_allocator_init
();
}
static
void
xen_write_cr2
(
unsigned
long
cr2
)
{
...
...
arch/x86/xen/p2m.c
View file @
f1d04b23
This diff is collapsed.
Click to expand it.
arch/x86/xen/setup.c
View file @
f1d04b23
This diff is collapsed.
Click to expand it.
arch/x86/xen/xen-ops.h
View file @
f1d04b23
...
...
@@ -29,12 +29,14 @@ void xen_build_mfn_list_list(void);
void
xen_setup_machphys_mapping
(
void
);
void
xen_setup_kernel_pagetable
(
pgd_t
*
pgd
,
unsigned
long
max_pfn
);
void
xen_reserve_top
(
void
);
extern
unsigned
long
xen_max_p2m_pfn
;
void
xen_mm_pin_all
(
void
);
void
xen_mm_unpin_all
(
void
);
void
xen_set_pat
(
u64
);
unsigned
long
__ref
xen_chk_extra_mem
(
unsigned
long
pfn
);
void
__init
xen_inv_extra_mem
(
void
);
void
__init
xen_remap_memory
(
void
);
char
*
__init
xen_memory_setup
(
void
);
char
*
xen_auto_xlated_memory_setup
(
void
);
void
__init
xen_arch_setup
(
void
);
...
...
@@ -47,7 +49,7 @@ void xen_hvm_init_shared_info(void);
void
xen_unplug_emulated_devices
(
void
);
void
__init
xen_build_dynamic_phys_to_machine
(
void
);
unsigned
long
__init
xen_revector
_p2m_tree
(
void
);
void
__init
xen_vmalloc
_p2m_tree
(
void
);
void
xen_init_irq_ops
(
void
);
void
xen_setup_timer
(
int
cpu
);
...
...
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