From patchwork Tue Aug 17 15:47:54 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 61925 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3CFA8B70CD for ; Wed, 18 Aug 2010 01:48:54 +1000 (EST) Received: from localhost ([127.0.0.1]:52752 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OlOPD-0008R9-Gj for incoming@patchwork.ozlabs.org; Tue, 17 Aug 2010 11:48:51 -0400 Received: from [140.186.70.92] (port=43995 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OlOON-0008QQ-0m for qemu-devel@nongnu.org; Tue, 17 Aug 2010 11:48:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OlOOL-0007EM-KX for qemu-devel@nongnu.org; Tue, 17 Aug 2010 11:47:58 -0400 Received: from cantor2.suse.de ([195.135.220.15]:37397 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OlOOL-0007Dq-Bb for qemu-devel@nongnu.org; Tue, 17 Aug 2010 11:47:57 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id E19568AD27; Tue, 17 Aug 2010 17:47:54 +0200 (CEST) From: Alexander Graf To: qemu-devel List Date: Tue, 17 Aug 2010 17:47:54 +0200 Message-Id: <1282060074-21593-1-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: Aurelien Jarno Subject: [Qemu-devel] [PATCH] PPC: Add PV hypercall transport through fw_cfg X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org On KVM for PPC we need to tell the guest which instructions to use when doing a hypercall. The clean way to do this is to go through an ioctl from userspace and passing it on to the guest using the device tree. So let's do the qemu part here: read out the hypercall and pass it on to the guest's fw_cfg so openBIOS can read it out and expose it again. Signed-off-by: Alexander Graf --- For this to work there's also an updated version of OpenBIOS required. --- hw/ppc.h | 3 +++ hw/ppc_newworld.c | 7 +++++++ hw/ppc_oldworld.c | 7 +++++++ target-ppc/kvm.c | 32 ++++++++++++++++++++++++++++++++ target-ppc/kvm_ppc.h | 1 + 5 files changed, 50 insertions(+), 0 deletions(-) diff --git a/hw/ppc.h b/hw/ppc.h index de13092..1251932 100644 --- a/hw/ppc.h +++ b/hw/ppc.h @@ -47,5 +47,8 @@ enum { #define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01) #define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02) #define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03) +#define FW_CFG_PPC_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05) +#define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06) +#define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07) #define PPC_SERIAL_MM_BAUDBASE 399193 diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index fbba9b6..f7c46b7 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -426,9 +426,16 @@ static void ppc_core99_init (ram_addr_t ram_size, fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); + fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM + uint8_t *hypercall; + fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); + hypercall = qemu_malloc(16); + kvmppc_get_hypercall(env, hypercall, 16); + fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); + fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 6b3ab89..6bd6555 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -398,9 +398,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size, fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); + fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM + uint8_t *hypercall; + fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); + hypercall = qemu_malloc(16); + kvmppc_get_hypercall(env, hypercall, 16); + fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); + fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 1079ce1..14d6365 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -327,6 +327,38 @@ uint32_t kvmppc_get_tbfreq(void) return retval; } +int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) +{ + uint32_t *hc = (uint32_t*)buf; + +#ifdef KVM_CAP_PPC_GET_PVINFO + struct kvm_ppc_pvinfo pvinfo; + + if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_PVINFO) && + !kvm_vm_ioctl(env->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) { + memcpy(buf, pvinfo.hcall, buf_len); + + return 0; + } +#endif + + /* + * Fallback to always fail hypercalls: + * + * li r3, -1 + * nop + * nop + * nop + */ + + hc[0] = 0x3860ffff; + hc[1] = 0x60000000; + hc[2] = 0x60000000; + hc[3] = 0x60000000; + + return 0; +} + bool kvm_arch_stop_on_emulation_error(CPUState *env) { return true; diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index e8d66e8..65e31c9 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -15,5 +15,6 @@ int kvmppc_read_host_property(const char *node_path, const char *prop, void *val, size_t len); uint32_t kvmppc_get_tbfreq(void); +int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len); #endif /* __KVM_PPC_H__ */