From patchwork Fri Oct 21 04:35:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 9388017 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EBA66607F0 for ; Fri, 21 Oct 2016 04:36:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D199629DDF for ; Fri, 21 Oct 2016 04:36:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C21BD29DE3; Fri, 21 Oct 2016 04:36:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 96DFE29DDF for ; Fri, 21 Oct 2016 04:36:29 +0000 (UTC) Received: from localhost ([::1]:58622 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bxRZE-0001LF-UH for patchwork-qemu-devel@patchwork.kernel.org; Fri, 21 Oct 2016 00:36:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43701) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bxRYp-0001JI-NK for qemu-devel@nongnu.org; Fri, 21 Oct 2016 00:36:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bxRYm-0001mY-Ha for qemu-devel@nongnu.org; Fri, 21 Oct 2016 00:36:03 -0400 Received: from mail-pf0-x243.google.com ([2607:f8b0:400e:c00::243]:34070) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bxRYm-0001lp-71; Fri, 21 Oct 2016 00:36:00 -0400 Received: by mail-pf0-x243.google.com with SMTP id 128so7429988pfz.1; Thu, 20 Oct 2016 21:36:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:in-reply-to:references :organization:mime-version:content-transfer-encoding; bh=xHl2iaGXZjqD4f3bHIVA/7RG7cEc6wFv66C8nzOrRLI=; b=CJIhY8Ow/RKn3xg/4Muav1BnKLI/47SlSgc8QQPeCYb0F9P9WDFF7ZTEeITjexQFO2 Hae6ZKsCoKYCAB6E1OPY/Q6EW7VmOV+SbxPDE9u/QGE0ZNzjJzcw+CKJ8vK57Nwtq7it DYGAZT2iihlgs10g0awf0+1tYmuGNnNCUnDl39NsQQ9wDlcW+SEaGijt4aoUm8o4eHKE BHAgF0PGLxoE9+3FJBhf8WCS6AHkfpxFJrDPFlwP+K7SJfT3rPI8IjIFQiyqSKREfgJ0 wJ1F3XT48XRCi5mYdzfmm33fGFy/hcObBGXwAx9C8YVv9Wluf2HVrfiWQdUTvSPC314L KDNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:organization:mime-version:content-transfer-encoding; bh=xHl2iaGXZjqD4f3bHIVA/7RG7cEc6wFv66C8nzOrRLI=; b=b0mlqjX+fEM7pWq60DDlcSbPCgxAElxeh7N+Ph8dbYs9Qi9g1xpInOIiRlX0dNMHm2 FA4seHPAUGLnPNf0LlGBpwgRkVsNj83o5tdo9nElMEwl3DUgqwexr+5VrSnWQ/U86d5T FbMT+LPjpZGV/uycMagy+ZsGzRKt30dHODNFjLhAY+JGkIz10F5uE/WoeWEU0nqW/Mkk bmsRn5FVwTNJm+YO8ZuXd2vfbs4RGQhzoNTf6odBmJwEyLLj3juEb5oFjCUdpN9Wd8/L /zaWNeP4JOsJOReU2OlbYN/7jZB5695LP51O3jT6VdhsTNFNN4zZ4C17BkX/0NRFnD0r iVzQ== X-Gm-Message-State: AA6/9RnhX8L40icVLdMpyorhB0RTxhqJRGQVrEYxP9CpBxtaDGd5soCwZgHRzsFXAr0qCA== X-Received: by 10.99.98.5 with SMTP id w5mr6324732pgb.77.1477024558640; Thu, 20 Oct 2016 21:35:58 -0700 (PDT) Received: from roar.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id r77sm862661pfb.2.2016.10.20.21.35.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 20 Oct 2016 21:35:57 -0700 (PDT) Date: Fri, 21 Oct 2016 15:35:43 +1100 From: Nicholas Piggin To: David Gibson Message-ID: <20161021153543.294dfa9d@roar.ozlabs.ibm.com> In-Reply-To: <20161021010954.GY11140@umbus.fritz.box> References: <20161020065912.16132-1-npiggin@gmail.com> <20161020065912.16132-3-npiggin@gmail.com> <20161021004058.074a7769@roar.ozlabs.ibm.com> <20161021010954.GY11140@umbus.fritz.box> Organization: IBM X-Mailer: Claws Mail 3.14.0 (GTK+ 2.24.31; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c00::243 Subject: [Qemu-devel] [PATCH v2] ppc: allow certain HV interrupts to be delivered to guests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, =?UTF-8?B?Q8OpZHJpYw==?= Le Goater , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP On Fri, 21 Oct 2016 12:09:54 +1100 David Gibson wrote: > On Fri, Oct 21, 2016 at 12:40:58AM +1100, Nicholas Piggin wrote: > > On Thu, 20 Oct 2016 15:08:07 +0200 > > Cédric Le Goater wrote: > > > > > On 10/20/2016 08:59 AM, Nicholas Piggin wrote: > > > > Signed-off-by: Nicholas Piggin > > > > --- > > > > target-ppc/excp_helper.c | 8 ++++++-- > > > > 1 file changed, 6 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > > > > index 53c4075..477af10 100644 > > > > --- a/target-ppc/excp_helper.c > > > > +++ b/target-ppc/excp_helper.c > > > > @@ -390,9 +390,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) > > > > /* indicate that we resumed from power save mode */ > > > > msr |= 0x10000; > > > > new_msr |= ((target_ulong)1 << MSR_ME); > > > > + new_msr |= (target_ulong)MSR_HVB; > > > > + } else { > > > > + /* The ISA specifies the HV bit is set when the hardware interrupt > > > > + * is raised, however when hypervisors deliver the exception to > > > > + * guests, it should not be set. > > > > + */ > > > > } > > > > - > > > > - new_msr |= (target_ulong)MSR_HVB; > > > > ail = 0; > > > > break; > > > > case POWERPC_EXCP_DSEG: /* Data segment exception */ > > > > > > > > > > should not that be cleared later on in powerpc_excp() by : > > > > > > env->msr = new_msr & env->msr_mask; > > > > > > ? but the routine is rather long so I might be missing a branch. > > > > No you're right, so it can't leak into the guest, phew! > > > > The problem I get is the interrupt code doing some things differently > > depending on on the HV bit. For example what I noticed is the guest > > losing its LE bit upon entry. > > > > Perhaps a cleaner way is for the system reset case to set new_msr > > according to the ISA, and then apply the msr_mask (or at least mask > > out HV) before calculating the exception model? Any preference? > > I think the proposed revision makes sense. > What do you think of this version? This fixes up machine check guest delivery as well. I'm sending this ahead of the new hcall patch, because it's a bugfix for existing code. I'll get around to the hcall again next week. Thanks, Nick ppc hypervisors have delivered system reset and machine check exception interrupts to guests in some situations (e.g., see FWNMI feature of LoPAPR, or NMI injection in QEMU). These exceptions are architected to set the HV bit in hardware, however when injected into a guest, the HV bit should be cleared. Current code masks off the HV bit before setting the new MSR, however this happens after the interrupt delivery model has calculated delivery mode for the exception. This can result in the guest's MSR LE bit being lost. Provide a new flag for HV exceptions to allow delivery to guests. The exception model masks out the HV bit. Also add another sanity check to ensure other such exceptions don't try to set HV in guest without setting guest_hv_excp Signed-off-by: Nicholas Piggin Reviewed-by: Cédric Le Goater --- target-ppc/excp_helper.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index 53c4075..1b18433 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -77,7 +77,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; target_ulong msr, new_msr, vector; - int srr0, srr1, asrr0, asrr1, lev, ail; + int srr0, srr1, asrr0, asrr1, lev, ail, guest_hv_excp; bool lpes0; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx @@ -149,6 +149,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) * * AIL is initialized here but can be cleared by * selected exceptions + * + * guest_hv_excp is a provision to raise HV architected + * exceptions in guests by delivering them with HV bit + * clear. System reset and machine check use this. */ #if defined(TARGET_PPC64) if (excp_model == POWERPC_EXCP_POWER7 || @@ -165,6 +169,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) lpes0 = true; ail = 0; } + guest_hv_excp = 0; /* Hypervisor emulation assistance interrupt only exists on server * arch 2.05 server or later. We also don't want to generate it if @@ -214,6 +219,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } new_msr |= (target_ulong)MSR_HVB; + guest_hv_excp = 1; ail = 0; /* machine check exceptions don't have ME set */ @@ -391,8 +397,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) msr |= 0x10000; new_msr |= ((target_ulong)1 << MSR_ME); } - new_msr |= (target_ulong)MSR_HVB; + guest_hv_excp = 1; ail = 0; break; case POWERPC_EXCP_DSEG: /* Data segment exception */ @@ -610,10 +616,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* Sanity check */ if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) { - cpu_abort(cs, "Trying to deliver HV exception %d with " + cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " "no HV support\n", excp); } + /* The ISA specifies the HV bit is set when the hardware interrupt + * is raised, however in some cases hypervisors deliver the exception + * to guests. HV should be cleared in that case. + */ + if (!(env->msr_mask & MSR_HVB) && (new_msr & MSR_HVB)) { + if (guest_hv_excp) { + new_msr &= ~MSR_HVB; + } else { + cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " + "no HV support\n", excp); + } + } + /* If any alternate SRR register are defined, duplicate saved values */ if (asrr0 != -1) { env->spr[asrr0] = env->spr[srr0];