Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752864AbdLLXs0 (ORCPT ); Tue, 12 Dec 2017 18:48:26 -0500 Received: from aserp2120.oracle.com ([141.146.126.78]:56952 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752723AbdLLXsX (ORCPT ); Tue, 12 Dec 2017 18:48:23 -0500 From: Maran Wilson To: pbonzini@redhat.com, jgross@suse.com, boris.ostrovsky@oracle.com, roger.pau@citrix.com, andrew.cooper3@citrix.com, hch@infradead.org, JBeulich@suse.com, x86@kernel.org, xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, rkrcmar@redhat.com Subject: [RFC PATCH v3 2/2] KVM: x86: Allow Qemu/KVM to use PVH entry point Date: Tue, 12 Dec 2017 15:42:31 -0800 Message-Id: <1513122151-5371-3-git-send-email-maran.wilson@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1513122151-5371-1-git-send-email-maran.wilson@oracle.com> References: <1513122151-5371-1-git-send-email-maran.wilson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8743 signatures=668646 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=903 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1712120334 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3608 Lines: 111 For certain applications it is desirable to rapidly boot a KVM virtual machine. In cases where legacy hardware and software support within the guest is not needed, Qemu should be able to boot directly into the uncompressed Linux kernel binary without the need to run firmware. There already exists an ABI to allow this for Xen PVH guests and the ABI is supported by Linux and FreeBSD: https://xenbits.xen.org/docs/unstable/misc/pvh.html This patch enables Qemu to use that same entry point for booting KVM guests. --- arch/x86/xen/enlighten_pvh.c | 51 +++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c index 98ab176..12f3716 100644 --- a/arch/x86/xen/enlighten_pvh.c +++ b/arch/x86/xen/enlighten_pvh.c @@ -31,21 +31,38 @@ static void xen_pvh_arch_setup(void) acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM; } -static void __init init_pvh_bootparams(void) +static void __init init_pvh_bootparams(bool xen_guest) { struct xen_memory_map memmap; int rc; memset(&pvh_bootparams, 0, sizeof(pvh_bootparams)); - memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_table); - set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_table); - rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); - if (rc) { - xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc); + if ((pvh_start_info.version > 0) && (pvh_start_info.memmap_entries)) { + struct hvm_memmap_table_entry *ep; + int i; + + ep = __va(pvh_start_info.memmap_paddr); + pvh_bootparams.e820_entries = pvh_start_info.memmap_entries; + + for (i = 0; i < pvh_bootparams.e820_entries ; i++, ep++) { + pvh_bootparams.e820_table[i].addr = ep->addr; + pvh_bootparams.e820_table[i].size = ep->size; + pvh_bootparams.e820_table[i].type = ep->type; + } + } else if (xen_guest) { + memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_table); + set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_table); + rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); + if (rc) { + xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc); + BUG(); + } + pvh_bootparams.e820_entries = memmap.nr_entries; + } else { + xen_raw_printk("Error: Could not find memory map\n"); BUG(); } - pvh_bootparams.e820_entries = memmap.nr_entries; if (pvh_bootparams.e820_entries < E820_MAX_ENTRIES_ZEROPAGE - 1) { pvh_bootparams.e820_table[pvh_bootparams.e820_entries].addr = @@ -76,7 +93,7 @@ static void __init init_pvh_bootparams(void) * environment (i.e. hardware_subarch 0). */ pvh_bootparams.hdr.version = 0x212; - pvh_bootparams.hdr.type_of_loader = (9 << 4) | 0; /* Xen loader */ + pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0; } /* @@ -85,8 +102,10 @@ static void __init init_pvh_bootparams(void) */ void __init xen_prepare_pvh(void) { - u32 msr; + + u32 msr = xen_cpuid_base(); u64 pfn; + bool xen_guest = !!msr; if (pvh_start_info.magic != XEN_HVM_START_MAGIC_VALUE) { xen_raw_printk("Error: Unexpected magic value (0x%08x)\n", @@ -94,13 +113,15 @@ void __init xen_prepare_pvh(void) BUG(); } - xen_pvh = 1; + if (xen_guest) { + xen_pvh = 1; - msr = cpuid_ebx(xen_cpuid_base() + 2); - pfn = __pa(hypercall_page); - wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32)); + msr = cpuid_ebx(msr + 2); + pfn = __pa(hypercall_page); + wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32)); - init_pvh_bootparams(); + x86_init.oem.arch_setup = xen_pvh_arch_setup; + } - x86_init.oem.arch_setup = xen_pvh_arch_setup; + init_pvh_bootparams(xen_guest); } -- 1.8.3.1