mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
[LINUX] Support variable hypervisor_virt_start.
Introduce a new elfnote that specifies the lower boundary the kernel wants to tolerate for the hypervisor hole. Signed-off-by: Jan Beulich <jbeulich@novell.com>
This commit is contained in:
1 parent
501330f105
commit
b63bf4c482
10 files changed
+31
-22
No files matched your search
@@ -9,7 +9,7 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <xen/interface/arch-x86_32.h>
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/elfnote.h>
|
||||
|
||||
/*
|
||||
@@ -192,6 +192,7 @@ ENTRY(cpu_gdt_table)
|
||||
#endif /* !CONFIG_XEN_COMPAT_030002 */
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, startup_32)
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, HYPERVISOR_VIRT_START)
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
|
||||
#ifdef CONFIG_X86_PAE
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
|
||||
|
||||
@@ -282,12 +282,6 @@ static int spurious_fault(struct pt_regs *regs,
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
/* Faults in hypervisor area are never spurious. */
|
||||
if (address >= HYPERVISOR_VIRT_START)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* Reserved-bit violation or user access to kernel space? */
|
||||
if (error_code & 0x0c)
|
||||
return 0;
|
||||
@@ -372,7 +366,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
|
||||
if (unlikely(address >= TASK_SIZE)) {
|
||||
#ifdef CONFIG_XEN
|
||||
/* Faults in hypervisor area can never be patched up. */
|
||||
if (address >= HYPERVISOR_VIRT_START)
|
||||
if (address >= hypervisor_virt_start)
|
||||
goto bad_area_nosemaphore;
|
||||
#endif
|
||||
if (!(error_code & 5))
|
||||
|
||||
@@ -130,7 +130,7 @@ static void __init page_table_range_init (unsigned long start, unsigned long end
|
||||
pud = pud_offset(pgd, vaddr);
|
||||
pmd = pmd_offset(pud, vaddr);
|
||||
for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
|
||||
if (vaddr < HYPERVISOR_VIRT_START && pmd_none(*pmd))
|
||||
if (vaddr < hypervisor_virt_start && pmd_none(*pmd))
|
||||
one_page_table_init(pmd);
|
||||
|
||||
vaddr += PMD_SIZE;
|
||||
@@ -187,7 +187,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
|
||||
pmd += pmd_idx;
|
||||
for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
|
||||
unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
|
||||
if (address >= HYPERVISOR_VIRT_START)
|
||||
if (address >= hypervisor_virt_start)
|
||||
continue;
|
||||
|
||||
/* Map with big pages if possible, otherwise create normal page tables. */
|
||||
@@ -410,7 +410,7 @@ static void __init pagetable_init (void)
|
||||
* created - mappings will be set by set_fixmap():
|
||||
*/
|
||||
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
|
||||
page_table_range_init(vaddr, 0, pgd_base);
|
||||
page_table_range_init(vaddr, hypervisor_virt_start, pgd_base);
|
||||
|
||||
permanent_kmaps_init(pgd_base);
|
||||
}
|
||||
|
||||
@@ -186,9 +186,16 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
|
||||
}
|
||||
|
||||
static int nr_fixmaps = 0;
|
||||
unsigned long hypervisor_virt_start = HYPERVISOR_VIRT_START;
|
||||
unsigned long __FIXADDR_TOP = (HYPERVISOR_VIRT_START - 2 * PAGE_SIZE);
|
||||
EXPORT_SYMBOL(__FIXADDR_TOP);
|
||||
|
||||
void __init set_fixaddr_top()
|
||||
{
|
||||
BUG_ON(nr_fixmaps > 0);
|
||||
__FIXADDR_TOP = hypervisor_virt_start - 2 * PAGE_SIZE;
|
||||
}
|
||||
|
||||
void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
|
||||
{
|
||||
unsigned long address = __fix_to_virt(idx);
|
||||
@@ -211,12 +218,6 @@ void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
|
||||
nr_fixmaps++;
|
||||
}
|
||||
|
||||
void set_fixaddr_top(unsigned long top)
|
||||
{
|
||||
BUG_ON(nr_fixmaps > 0);
|
||||
__FIXADDR_TOP = top - PAGE_SIZE;
|
||||
}
|
||||
|
||||
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
|
||||
|
||||
@@ -98,7 +98,7 @@ enum fixed_addresses {
|
||||
extern void __set_fixmap(enum fixed_addresses idx,
|
||||
maddr_t phys, pgprot_t flags);
|
||||
|
||||
extern void set_fixaddr_top(unsigned long top);
|
||||
extern void set_fixaddr_top(void);
|
||||
|
||||
#define set_fixmap(idx, phys) \
|
||||
__set_fixmap(idx, phys, PAGE_KERNEL)
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
|
||||
extern shared_info_t *HYPERVISOR_shared_info;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
extern unsigned long hypervisor_virt_start;
|
||||
#endif
|
||||
|
||||
/* arch/xen/i386/kernel/setup.c */
|
||||
extern start_info_t *xen_start_info;
|
||||
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#define PGDIR_SHIFT 22
|
||||
#define PTRS_PER_PGD 1024
|
||||
#define PTRS_PER_PGD_NO_HV (HYPERVISOR_VIRT_START >> PGDIR_SHIFT)
|
||||
|
||||
/*
|
||||
* the i386 is two-level, so we don't really have any
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
#define PGDIR_SHIFT 30
|
||||
#define PTRS_PER_PGD 4
|
||||
#define PTRS_PER_PGD_NO_HV 4
|
||||
|
||||
/*
|
||||
* PMD_SHIFT determines the size of the area a middle-level
|
||||
|
||||
@@ -92,8 +92,10 @@ static void __init machine_specific_arch_setup(void)
|
||||
#endif
|
||||
|
||||
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
|
||||
&pp) == 0)
|
||||
set_fixaddr_top(pp.virt_start - PAGE_SIZE);
|
||||
&pp) == 0) {
|
||||
hypervisor_virt_start = pp.virt_start;
|
||||
set_fixaddr_top();
|
||||
}
|
||||
|
||||
machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
|
||||
machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
|
||||
|
||||
@@ -138,6 +138,15 @@
|
||||
*/
|
||||
#define XEN_ELFNOTE_BSD_SYMTAB 11
|
||||
|
||||
/*
|
||||
* The lowest address the hypervisor hole can begin at (numeric).
|
||||
*
|
||||
* This must not be set higher than HYPERVISOR_VIRT_START. Its presence
|
||||
* also indicates to the hypervisor that the kernel can deal with the
|
||||
* hole starting at a higher address.
|
||||
*/
|
||||
#define XEN_ELFNOTE_HV_START_LOW 12
|
||||
|
||||
#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
|
||||
|
||||
/*
|
||||
|
||||