[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 12/18] xen: setup Xen specific data for PVH
Initialize the needed Xen specific data. This is: - the Xen start of day page containing the console and Xenstore ring page PFN and event channel - the grant table - the shared info page Set the RSDP address for the guest from the start_info page passed as boot parameter. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- grub-core/kern/i386/xen/pvh.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c index b4933b454..93ed68245 100644 --- a/grub-core/kern/i386/xen/pvh.c +++ b/grub-core/kern/i386/xen/pvh.c @@ -24,6 +24,7 @@ #include <grub/xen.h> #include <grub/i386/linux.h> #include <grub/machine/kernel.h> +#include <xen/hvm/params.h> #include <xen/memory.h> struct xen_machine_mmap_entry @@ -39,6 +40,7 @@ static struct { char _entry[32]; } hypercall_page[128] __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE))); static grub_uint32_t xen_cpuid_base; +static struct start_info grub_xen_start_page; static struct xen_machine_mmap_entry map[128]; static unsigned int nr_map_entries; @@ -104,6 +106,36 @@ grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0, return __res; } +static grub_uint32_t +grub_xen_get_param (int idx) +{ + struct xen_hvm_param xhv; + int r; + + xhv.domid = DOMID_SELF; + xhv.index = idx; + r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param, + (grub_uint32_t) (&xhv), 0, 0, 0, 0); + if (r < 0) + grub_xen_early_halt (); + return xhv.value; +} + +static void * +grub_xen_add_physmap (unsigned int space, void *addr) +{ + struct xen_add_to_physmap xatp; + + xatp.domid = DOMID_SELF; + xatp.idx = 0; + xatp.space = space; + xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE; + if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap, + (grub_uint32_t) (&xatp), 0, 0, 0, 0)) + grub_xen_early_halt (); + return addr; +} + static void grub_xen_sort_mmap (void) { @@ -190,12 +222,87 @@ grub_xen_get_mmap (void) grub_xen_sort_mmap (); } +static grub_uint64_t +grub_xen_find_page (grub_uint64_t start) +{ + unsigned int i, j; + grub_uint64_t last = start; + + /* Try to find a e820 map hole below 4G. */ + for (i = 0; i < nr_map_entries; i++) + { + if (last > map[i].addr + map[i].len) + continue; + if (last < map[i].addr) + return last; + if ((map[i].addr >> 32) || ((map[i].addr + map[i].len) >> 32)) + break; + last = map[i].addr + map[i].len; + } + if (i == nr_map_entries) + return last; + + /* No hole found, use the highest RAM page below 4G and reserve it. */ + if (nr_map_entries == ARRAY_SIZE(map)) + grub_xen_early_halt (); + j = 0; + for (i = 0; i < nr_map_entries; i++) + { + if (map[i].type != GRUB_MEMORY_AVAILABLE) + continue; + if (map[i].addr >> 32) + break; + j = i; + if ((map[i].addr + map[i].len) >> 32) + break; + } + if (map[j].type != GRUB_MEMORY_AVAILABLE) + grub_xen_early_halt (); + if ((map[i].addr + map[i].len) >> 32) + last = (1ULL << 32) - GRUB_XEN_PAGE_SIZE; + else + last = map[i].addr + map[i].len - GRUB_XEN_PAGE_SIZE; + map[nr_map_entries].addr = last; + map[nr_map_entries].len = GRUB_XEN_PAGE_SIZE; + map[nr_map_entries].type = GRUB_MEMORY_RESERVED; + nr_map_entries++; + grub_xen_sort_mmap (); + + return last; +} + void grub_xen_setup_pvh (void) { + grub_addr_t par; + grub_xen_cpuid_base (); grub_xen_setup_hypercall_page (); grub_xen_get_mmap (); + + /* Setup Xen data. */ + grub_xen_start_page_addr = &grub_xen_start_page; + + par = grub_xen_get_param (HVM_PARAM_CONSOLE_PFN); + grub_xen_start_page_addr->console.domU.mfn = par; + grub_xen_xcons = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE); + par = grub_xen_get_param (HVM_PARAM_CONSOLE_EVTCHN); + grub_xen_start_page_addr->console.domU.evtchn = par; + + par = grub_xen_get_param (HVM_PARAM_STORE_PFN); + grub_xen_start_page_addr->store_mfn = par; + grub_xen_xenstore = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE); + par = grub_xen_get_param (HVM_PARAM_STORE_EVTCHN); + grub_xen_start_page_addr->store_evtchn = par; + + par = grub_xen_find_page (0); + grub_xen_grant_table = grub_xen_add_physmap (XENMAPSPACE_grant_table, + (void *) par); + par = grub_xen_find_page (par + GRUB_XEN_PAGE_SIZE); + grub_xen_shared_info = grub_xen_add_physmap (XENMAPSPACE_shared_info, + (void *) par); + + grub_rsdp_addr = pvh_start_info->rsdp_paddr; } grub_err_t -- 2.16.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |