From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1aYuBD-00028Q-IP for mharc-grub-devel@gnu.org; Thu, 25 Feb 2016 06:33:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58272) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aYuB5-0001tu-O0 for grub-devel@gnu.org; Thu, 25 Feb 2016 06:33:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aYuB2-0000EG-St for grub-devel@gnu.org; Thu, 25 Feb 2016 06:33:51 -0500 Received: from mx2.suse.de ([195.135.220.15]:34225) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aYuB2-0000DW-K3 for grub-devel@gnu.org; Thu, 25 Feb 2016 06:33:48 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id AC9B5AD7D; Thu, 25 Feb 2016 11:33:47 +0000 (UTC) From: Juergen Gross To: grub-devel@gnu.org Subject: [PATCH v5 11/11] xen: add capability to load p2m list outside of kernel mapping Date: Thu, 25 Feb 2016 12:33:37 +0100 Message-Id: <1456400017-5789-12-git-send-email-jgross@suse.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1456400017-5789-1-git-send-email-jgross@suse.com> References: <1456400017-5789-1-git-send-email-jgross@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Cc: Juergen Gross , phcoder@gmail.com, daniel.kiper@oracle.com, mchang@suse.com, xen-devel@lists.xen.org X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Feb 2016 11:33:53 -0000 Modern pvops linux kernels support a p2m list not covered by the kernel mapping. This capability is flagged by an elf-note specifying the virtual address the kernel is expecting the p2m list to be mapped to. In case the elf-note is set by the kernel don't place the p2m list into the kernel mapping, but map it to the given address. This will allow to support domains with larger memory, as the kernel mapping is limited to 2GB and a domain with huge memory in the TB range will have a p2m list larger than this. Signed-off-by: Juergen Gross Reviewed-by: Daniel Kiper --- grub-core/loader/i386/xen.c | 53 +++++++++++++++++++++++++++++++------- grub-core/loader/i386/xen_fileXX.c | 4 +++ include/grub/xen_file.h | 2 ++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c index 5bcfde8..9bf8da8 100644 --- a/grub-core/loader/i386/xen.c +++ b/grub-core/loader/i386/xen.c @@ -313,24 +313,50 @@ static grub_err_t grub_xen_p2m_alloc (void) { grub_relocator_chunk_t ch; - grub_size_t p2msize; + grub_size_t p2msize, p2malloc; grub_err_t err; + struct grub_xen_mapping *map; if (xen_state.virt_mfn_list) return GRUB_ERR_NONE; + map = xen_state.mappings + xen_state.n_mappings; + p2msize = ALIGN_UP (sizeof (grub_xen_mfn_t) * + grub_xen_start_page_addr->nr_pages, PAGE_SIZE); + if (xen_state.xen_inf.has_p2m_base) + { + err = get_pgtable_size (xen_state.xen_inf.p2m_base, + xen_state.xen_inf.p2m_base + p2msize, + (xen_state.max_addr + p2msize) >> PAGE_SHIFT); + if (err) + return err; + + map->area.pfn_start = xen_state.max_addr >> PAGE_SHIFT; + p2malloc = p2msize + page2offset (map->area.n_pt_pages); + xen_state.n_mappings++; + xen_state.next_start.mfn_list = xen_state.xen_inf.p2m_base; + xen_state.next_start.first_p2m_pfn = map->area.pfn_start; + xen_state.next_start.nr_p2m_frames = p2malloc >> PAGE_SHIFT; + } + else + { + xen_state.next_start.mfn_list = + xen_state.max_addr + xen_state.xen_inf.virt_base; + p2malloc = p2msize; + } + xen_state.state.mfn_list = xen_state.max_addr; - xen_state.next_start.mfn_list = - xen_state.max_addr + xen_state.xen_inf.virt_base; - p2msize = sizeof (grub_xen_mfn_t) * grub_xen_start_page_addr->nr_pages; err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, p2msize); + xen_state.max_addr, p2malloc); if (err) return err; xen_state.virt_mfn_list = get_virtual_current_address (ch); + if (xen_state.xen_inf.has_p2m_base) + map->where = (grub_uint64_t *) xen_state.virt_mfn_list + + p2msize / sizeof (grub_uint64_t); grub_memcpy (xen_state.virt_mfn_list, (void *) grub_xen_start_page_addr->mfn_list, p2msize); - xen_state.max_addr = ALIGN_UP (xen_state.max_addr + p2msize, PAGE_SIZE); + xen_state.max_addr += p2malloc; return GRUB_ERR_NONE; } @@ -447,9 +473,12 @@ grub_xen_alloc_final (void) { grub_err_t err; - err = grub_xen_p2m_alloc (); - if (err) - return err; + if (!xen_state.xen_inf.has_p2m_base) + { + err = grub_xen_p2m_alloc (); + if (err) + return err; + } err = grub_xen_special_alloc (); if (err) return err; @@ -474,6 +503,12 @@ grub_xen_boot (void) err = grub_xen_alloc_final (); if (err) return err; + if (xen_state.xen_inf.has_p2m_base) + { + err = grub_xen_p2m_alloc (); + if (err) + return err; + } err = set_mfns (xen_state.console_pfn); if (err) diff --git a/grub-core/loader/i386/xen_fileXX.c b/grub-core/loader/i386/xen_fileXX.c index 8751174..fb66e66 100644 --- a/grub-core/loader/i386/xen_fileXX.c +++ b/grub-core/loader/i386/xen_fileXX.c @@ -261,6 +261,10 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi, descsz == 2 ? 2 : 3) == 0) xi->arch = GRUB_XEN_FILE_I386; break; + case XEN_ELFNOTE_INIT_P2M: + xi->p2m_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc); + xi->has_p2m_base = 1; + break; case XEN_ELFNOTE_MOD_START_PFN: xi->unmapped_initrd = !!grub_le_to_cpu32(*(grub_uint32_t *) desc); break; diff --git a/include/grub/xen_file.h b/include/grub/xen_file.h index ed749fa..6587999 100644 --- a/include/grub/xen_file.h +++ b/include/grub/xen_file.h @@ -32,9 +32,11 @@ struct grub_xen_file_info grub_uint64_t entry_point; grub_uint64_t hypercall_page; grub_uint64_t paddr_offset; + grub_uint64_t p2m_base; int has_hypercall_page; int has_note; int has_xen_guest; + int has_p2m_base; int extended_cr3; int unmapped_initrd; enum -- 2.6.2