Skip to content

Commit

Permalink
xen: implement XENMEM_machphys_mapping
Browse files Browse the repository at this point in the history
This hypercall allows Xen to specify a non-default location for the
machine to physical mapping. This capability is used when running a 32
bit domain 0 on a 64 bit hypervisor to shrink the hypervisor hole to
exactly the size required.

[ Impact: add Xen hypercall definitions ]

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
  • Loading branch information
Ian Campbell authored and Jeremy Fitzhardinge committed Nov 12, 2010
1 parent 9ec23a7 commit 7e77506
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 18 deletions.
6 changes: 3 additions & 3 deletions arch/x86/include/asm/xen/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ DEFINE_GUEST_HANDLE(void);
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
#endif

#ifndef machine_to_phys_mapping
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
#endif
#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT)

/* Maximum number of virtual CPUs in multi-processor guests. */
#define MAX_VIRT_CPUS 32
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/include/asm/xen/interface_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
/* And the trap vector is... */
#define TRAP_INSTR "int $0x82"

#define __MACH2PHYS_VIRT_START 0xF5800000
#define __MACH2PHYS_VIRT_END 0xF6800000

#define __MACH2PHYS_SHIFT 2

/*
* Virtual addresses beyond this are not modifiable by guest OSes. The
* machine->physical mapping table starts at this address, read-only.
Expand Down
13 changes: 1 addition & 12 deletions arch/x86/include/asm/xen/interface_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,7 @@
#define __HYPERVISOR_VIRT_END 0xFFFF880000000000
#define __MACH2PHYS_VIRT_START 0xFFFF800000000000
#define __MACH2PHYS_VIRT_END 0xFFFF804000000000

#ifndef HYPERVISOR_VIRT_START
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END)
#endif

#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
#ifndef machine_to_phys_mapping
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
#endif
#define __MACH2PHYS_SHIFT 3

/*
* int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
Expand Down
7 changes: 4 additions & 3 deletions arch/x86/include/asm/xen/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/pfn.h>
#include <linux/mm.h>

#include <asm/uaccess.h>
#include <asm/page.h>
Expand Down Expand Up @@ -35,6 +36,8 @@ typedef struct xpaddr {
#define MAX_DOMAIN_PAGES \
((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))

extern unsigned long *machine_to_phys_mapping;
extern unsigned int machine_to_phys_order;

extern unsigned long get_phys_to_machine(unsigned long pfn);
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
Expand Down Expand Up @@ -69,10 +72,8 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
if (xen_feature(XENFEAT_auto_translated_physmap))
return mfn;

#if 0
if (unlikely((mfn >> machine_to_phys_order) != 0))
return max_mapnr;
#endif
return ~0;

pfn = 0;
/*
Expand Down
7 changes: 7 additions & 0 deletions arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
enum xen_domain_type xen_domain_type = XEN_NATIVE;
EXPORT_SYMBOL_GPL(xen_domain_type);

unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
EXPORT_SYMBOL(machine_to_phys_mapping);
unsigned int machine_to_phys_order;
EXPORT_SYMBOL(machine_to_phys_order);

struct start_info *xen_start_info;
EXPORT_SYMBOL_GPL(xen_start_info);

Expand Down Expand Up @@ -1097,6 +1102,8 @@ asmlinkage void __init xen_start_kernel(void)

xen_domain_type = XEN_PV_DOMAIN;

xen_setup_machphys_mapping();

/* Install Xen paravirt ops */
pv_info = xen_info;
pv_init_ops = xen_init_ops;
Expand Down
14 changes: 14 additions & 0 deletions arch/x86/xen/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
set_page_prot(pmd, PAGE_KERNEL_RO);
}

void __init xen_setup_machphys_mapping(void)
{
struct xen_machphys_mapping mapping;
unsigned long machine_to_phys_nr_ents;

if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
machine_to_phys_mapping = (unsigned long *)mapping.v_start;
machine_to_phys_nr_ents = mapping.max_mfn + 1;
} else {
machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
}
machine_to_phys_order = fls(machine_to_phys_nr_ents - 1);
}

#ifdef CONFIG_X86_64
static void convert_pfn_mfn(void *v)
{
Expand Down
13 changes: 13 additions & 0 deletions include/xen/interface/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@ struct xen_machphys_mfn_list {
};
DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list);

/*
* Returns the location in virtual address space of the machine_to_phys
* mapping table. Architectures which do not have a m2p table, or which do not
* map it by default into guest address space, do not implement this command.
* arg == addr of xen_machphys_mapping_t.
*/
#define XENMEM_machphys_mapping 12
struct xen_machphys_mapping {
unsigned long v_start, v_end; /* Start and end virtual addresses. */
unsigned long max_mfn; /* Maximum MFN that can be looked up. */
};
DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);

/*
* Sets the GPFN at which a particular page appears in the specified guest's
* pseudophysical address space.
Expand Down

0 comments on commit 7e77506

Please sign in to comment.