From patchwork Sun Sep 22 14:44:55 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Borislav Petkov X-Patchwork-Id: 2924481 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id F1128BFF05 for ; Sun, 22 Sep 2013 14:46:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1A9CF200FE for ; Sun, 22 Sep 2013 14:46:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 160CD2010E for ; Sun, 22 Sep 2013 14:46:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752613Ab3IVOpk (ORCPT ); Sun, 22 Sep 2013 10:45:40 -0400 Received: from mail.skyhub.de ([78.46.96.112]:53493 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752384Ab3IVOpI (ORCPT ); Sun, 22 Sep 2013 10:45:08 -0400 X-Virus-Scanned: Nedap ESD1 at mail.skyhub.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alien8.de; s=alien8; t=1379861106; bh=L9HCkb6Z8UXDfyFwkh5EcL5xJEOrz35RKY6sZBc+gTA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=AVbH pLOLY5aK1Hxtc6eh1hyKMHHFtzfUaXeuFIaboxtEHu1fbFzodi/lj+xNQ0NNNUtn7P3 SZMTL+YpNJvVDV/mHRDAOLOsvoP4jm991AsbN99KTXmpTbyZGBKEHNrM9MSXbvf5yls Iadv1yCXvkomlL6e/mjWgenyMS80C5ACE= Received: from mail.skyhub.de ([127.0.0.1]) by localhost (door.skyhub.de [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 8taWkCU-9cy5; Sun, 22 Sep 2013 16:45:06 +0200 (CEST) Received: from liondog.tnic (p54B47BC4.dip0.t-ipconnect.de [84.180.123.196]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.skyhub.de (SuperMail on ZX Spectrum 128k) with ESMTPSA id 423311DA242; Sun, 22 Sep 2013 16:45:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alien8.de; s=alien8; t=1379861105; bh=L9HCkb6Z8UXDfyFwkh5EcL5xJEOrz35RKY6sZBc+gTA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=llV/ MYIuOug7Uzr5azJUVBYwxScSX18jDRFEsxUptBG+DAqkJRAkhU+Cv/1FjcNDTp/k0mz agUQ3ndYP9TTeHBXKGlBbbaFdKJ55bKAoryJe2Mb/TVtGZFqtheqBV+83EiucZ7YkGJ 9sK+CJAzjNiiQ2VmU+8F5qxDIKkamp8IY= Received: by liondog.tnic (Postfix, from userid 1000) id 02F0A10219F; Sun, 22 Sep 2013 16:44:57 +0200 (CEST) From: Borislav Petkov To: LKML Cc: Borislav Petkov , "H. Peter Anvin" , Gleb Natapov , Paolo Bonzini , Andre Przywara , Joerg Roedel , X86 ML , KVM Subject: [PATCH 6/6] qemu: Add support for emulated CPU features Date: Sun, 22 Sep 2013 16:44:55 +0200 Message-Id: <1379861095-628-7-git-send-email-bp@alien8.de> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1379861095-628-1-git-send-email-bp@alien8.de> References: <1379861095-628-1-git-send-email-bp@alien8.de> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-9.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Borislav Petkov Add support for the KVM_GET_EMULATED_CPUID ioctl and leave feature bits enabled, when requested by userspace, if kvm emulates them. Signed-off-by: Borislav Petkov --- include/sysemu/kvm.h | 4 ++++ linux-headers/linux/kvm.h | 4 ++++ target-i386/cpu.c | 7 +++++++ target-i386/kvm.c | 38 ++++++++++++++++++++++++++++++++++---- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 9bbe3db1464e..8eda1ada848a 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -265,6 +265,10 @@ int kvm_check_extension(KVMState *s, unsigned int extension); uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function, uint32_t index, int reg); + +uint32_t kvm_arch_get_emulated_cpuid(KVMState *env, uint32_t function, + uint32_t index, int reg); + void kvm_cpu_synchronize_state(CPUState *cpu); /* generic hooks - to be moved/refactored once there are more users */ diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c614070662e1..edc8f2db1f8d 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -541,6 +541,7 @@ struct kvm_ppc_smmu_info { #define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06 #define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 #define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 +#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2) /* * Extension capability list. @@ -666,6 +667,9 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_IRQ_MPIC 90 #define KVM_CAP_PPC_RTAS 91 #define KVM_CAP_IRQ_XICS 92 +#define KVM_CAP_ARM_EL1_32BIT 93 +#define KVM_CAP_SPAPR_MULTITCE 94 +#define KVM_CAP_EXT_EMUL_CPUID 95 #ifdef KVM_CAP_IRQ_ROUTING diff --git a/target-i386/cpu.c b/target-i386/cpu.c index c36345e426d7..5406348ceb4a 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1850,7 +1850,14 @@ static void filter_features_for_kvm(X86CPU *cpu) wi->cpuid_ecx, wi->cpuid_reg); uint32_t requested_features = env->features[w]; + + uint32_t emul_features = kvm_arch_get_emulated_cpuid(s, wi->cpuid_eax, + wi->cpuid_ecx, + wi->cpuid_reg); + env->features[w] &= host_feat; + env->features[w] |= (requested_features & emul_features); + cpu->filtered_features[w] = requested_features & ~env->features[w]; } } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 749aa09a21a6..7f598f01bda5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -80,7 +80,7 @@ bool kvm_allows_irq0_override(void) return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing(); } -static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) +static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int ioctl, int max) { struct kvm_cpuid2 *cpuid; int r, size; @@ -88,7 +88,7 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) size = sizeof(*cpuid) + max * sizeof(*cpuid->entries); cpuid = (struct kvm_cpuid2 *)g_malloc0(size); cpuid->nent = max; - r = kvm_ioctl(s, KVM_GET_SUPPORTED_CPUID, cpuid); + r = kvm_ioctl(s, ioctl, cpuid); if (r == 0 && cpuid->nent >= max) { r = -E2BIG; } @@ -97,7 +97,10 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) g_free(cpuid); return NULL; } else { - fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n", + fprintf(stderr, "%s failed: %s\n", + (ioctl == (int)KVM_GET_SUPPORTED_CPUID + ? "KVM_GET_SUPPORTED_CPUID" + : "KVM_GET_EMULATED_CPUID"), strerror(-r)); exit(1); } @@ -112,7 +115,17 @@ static struct kvm_cpuid2 *get_supported_cpuid(KVMState *s) { struct kvm_cpuid2 *cpuid; int max = 1; - while ((cpuid = try_get_cpuid(s, max)) == NULL) { + while ((cpuid = try_get_cpuid(s, KVM_GET_SUPPORTED_CPUID, max)) == NULL) { + max *= 2; + } + return cpuid; +} + +static struct kvm_cpuid2 *get_emulated_cpuid(KVMState *s) +{ + struct kvm_cpuid2 *cpuid; + int max = 1; + while ((cpuid = try_get_cpuid(s, KVM_GET_EMULATED_CPUID, max)) == NULL) { max *= 2; } return cpuid; @@ -241,6 +254,23 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, return ret; } +uint32_t kvm_arch_get_emulated_cpuid(KVMState *s, uint32_t function, + uint32_t index, int reg) +{ + struct kvm_cpuid2 *cpuid __attribute__((unused)); + + if (!kvm_check_extension(s, KVM_CAP_EXT_EMUL_CPUID)) + return 0; + + cpuid = get_emulated_cpuid(s); + + struct kvm_cpuid_entry2 *entry = cpuid_find_entry(cpuid, function, index); + if (entry) + return cpuid_entry_get_reg(entry, reg); + + return 0; +} + typedef struct HWPoisonPage { ram_addr_t ram_addr; QLIST_ENTRY(HWPoisonPage) list;