Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752479AbdLGWrK (ORCPT ); Thu, 7 Dec 2017 17:47:10 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:44669 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750993AbdLGWrI (ORCPT ); Thu, 7 Dec 2017 17:47:08 -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, 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, JBeulich@suse.com Subject: [RFC PATCH v2 2/2] KVM: x86: Allow Qemu/KVM to use PVH entry point Date: Thu, 7 Dec 2017 14:45:15 -0800 Message-Id: <1512686715-11488-3-git-send-email-maran.wilson@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1512686715-11488-1-git-send-email-maran.wilson@oracle.com> References: <1512686715-11488-1-git-send-email-maran.wilson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8738 signatures=668644 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-1712070332 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3493 Lines: 108 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 | 48 ++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c index 98ab176..f11fbfc 100644 --- a/arch/x86/xen/enlighten_pvh.c +++ b/arch/x86/xen/enlighten_pvh.c @@ -31,21 +31,35 @@ 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 boot_e820_entry *ep; + int idx; + + ep = __va(pvh_start_info.memmap_paddr); + pvh_bootparams.e820_entries = pvh_start_info.memmap_entries; + + for (idx = 0; idx < pvh_bootparams.e820_entries ; idx++, ep++) + pvh_bootparams.e820_table[idx] = *ep; + } 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 +90,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 +99,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 +110,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