Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp387672pxk; Thu, 24 Sep 2020 08:01:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxNbeS5oFqJu1n7fTNYzjZFMa8AsvB7ettviNJ4wWMCFlVAXWukxKfyWaI5dKgYl+hTc+uh X-Received: by 2002:adf:b1d8:: with SMTP id r24mr213468wra.194.1600959705095; Thu, 24 Sep 2020 08:01:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600959705; cv=none; d=google.com; s=arc-20160816; b=wajmGS5AZTwW9vMk88as17tl9BO0oOAaCgt/c0TKAm54N9wum6FVz9NMx4fPL7ds0F FFBcyx4B1i+UXN4sjRsZK8CcWv2AXQqJlafXodTcc7JOMVs4WcxW9D7qZtcXiVszoNKa ChFQSAc6VUfuhqP1olpeLtb7YrcbUO70yKocjuRSr45tS1S8Nk41L0e50g7Yk3NTZAvc UXg6V2YYTlolAEwPDV80KJW3poMjF0+TpTpu0bfZEaPG5x2XANNRwYodZ2UrUfcJvhz/ QixmsHZkavh9pgR1N28GJV/RbW68Acq9wMoXiuqdRsqFTrwQpP8e86e4yCkSf9fE4HQO F+jA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=NiAX/lKhBwtj/b+yjV6cXPKWwcBGqpXA7p5pUSchAm0=; b=m6rBKAE8yUowveY8Zpte1H2GZ9QOrReyB4HMF+Sioe5ZCxLRmnPNRbehRuu1xzuT79 PyU1dP7wN9yPvUwPTgjcZm0aknYy50jyiak9QPnvtaOngrBTM8WvGXGrzvhKp/0qWIyz tVR8Gt2UWSLHNMuhoFGsrP7bHyZygz2TN75kp5770iWMzAuDlT0RgDY7r8TW1AVSQ4OO gJ5Ioqba5jYFkM4YwQ0qbS6JbPDrb6g61pMRMI9tcjGVkfCJI4Kkpq+uLpOfMDCTR59i uI33rrZfyxFJNymP7EXd1X/F9ng5CyC1LGva+hnu866AjPy2OW39+rAFkLiAqWkV0+dW lf1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2020-01-29 header.b=vD7Wb2hE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id qq22si2184538ejb.281.2020.09.24.08.01.19; Thu, 24 Sep 2020 08:01:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2020-01-29 header.b=vD7Wb2hE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728455AbgIXO6q (ORCPT + 99 others); Thu, 24 Sep 2020 10:58:46 -0400 Received: from aserp2120.oracle.com ([141.146.126.78]:55966 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728424AbgIXO6l (ORCPT ); Thu, 24 Sep 2020 10:58:41 -0400 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 08OEtGqE037460; Thu, 24 Sep 2020 14:58:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2020-01-29; bh=NiAX/lKhBwtj/b+yjV6cXPKWwcBGqpXA7p5pUSchAm0=; b=vD7Wb2hE0pZQ+BeUmSaNSTuKgTZLdB2OSQDork8YNrZIlKQnKWTrRriOQWEvr4fOpZ8F 7l2AKA351i5WLNejNJaLNVKCkYfcd99x+hqmbLyCufqV+UJibijufGVOyT7uauKMhFJ9 FA/n5Kd/wpes59nIiav7hqNUFcJkMYCHuafxChDxoiylu7iUVvTWngp2ab7bccHmtOUf C7miJPOuWQ5V7oSFyqqeJoOk+SG9d+4qhIkLYY/1u3tHv/Xm8DDnitIOMJ2kZOFyLsQO idAwfNvewodWonkZV8qcdVVZzb7rqdjwrmqTM6sw2ojECHzsSI6sQSfk/Xs8RtUih+ha xw== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by aserp2120.oracle.com with ESMTP id 33q5rgq585-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 24 Sep 2020 14:58:18 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 08OEuApX177221; Thu, 24 Sep 2020 14:58:18 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserp3020.oracle.com with ESMTP id 33r28x3vkd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 24 Sep 2020 14:58:18 +0000 Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id 08OEwFG7000849; Thu, 24 Sep 2020 14:58:15 GMT Received: from disposition.us.oracle.com (/10.152.32.81) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 24 Sep 2020 07:58:15 -0700 From: Ross Philipson To: linux-kernel@vger.kernel.org, x86@kernel.org, iommu@lists.linux-foundation.org, linux-integrity@vger.kernel.org, linux-doc@vger.kernel.org Cc: ross.philipson@oracle.com, dpsmith@apertussolutions.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, hpa@zytor.com, luto@amacapital.net, trenchboot-devel@googlegroups.com Subject: [PATCH 09/13] x86: Secure Launch SMP bringup support Date: Thu, 24 Sep 2020 10:58:37 -0400 Message-Id: <1600959521-24158-10-git-send-email-ross.philipson@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1600959521-24158-1-git-send-email-ross.philipson@oracle.com> References: <1600959521-24158-1-git-send-email-ross.philipson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9753 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 mlxlogscore=999 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 spamscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2006250000 definitions=main-2009240114 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9753 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 impostorscore=0 clxscore=1015 suspectscore=0 phishscore=0 malwarescore=0 priorityscore=1501 mlxlogscore=999 adultscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2006250000 definitions=main-2009240114 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Intel, the APs are left in a well documented state after TXT performs the late launch. Specifically they cannot have #INIT asserted on them so a standard startup via INIT/SIPI/SIPI cannot be performed. Instead the early SL stub code parked the APs in a pause/jmp loop waiting for an NMI. The modified SMP boot code is called for the Secure Launch case. The jump address for the RM piggy entry point is fixed up in the jump where the APs are waiting and an NMI IPI is sent to the AP. The AP vectors to the Secure Launch entry point in the RM piggy which mimics what the real mode code would do then jumps the the standard RM piggy protected mode entry point. Signed-off-by: Ross Philipson --- arch/x86/include/asm/realmode.h | 3 ++ arch/x86/kernel/smpboot.c | 86 ++++++++++++++++++++++++++++++++++++ arch/x86/realmode/rm/header.S | 3 ++ arch/x86/realmode/rm/trampoline_64.S | 37 ++++++++++++++++ 4 files changed, 129 insertions(+) diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index b35030e..20bc283 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h @@ -34,6 +34,9 @@ struct real_mode_header { #ifdef CONFIG_X86_64 u32 machine_real_restart_seg; #endif +#ifdef CONFIG_SECURE_LAUNCH + u32 sl_trampoline_start32; +#endif }; /* This must match data at realmode/rm/trampoline_{32,64}.S */ diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index f5ef689..0ca0b07 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -1017,6 +1018,83 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle) return 0; } +#ifdef CONFIG_SECURE_LAUNCH + +static atomic_t first_ap_only = {1}; + +/* + * Called to fix the long jump address for the waiting APs to vector to + * the correct startup location in the Secure Launch stub in the rmpiggy. + */ +static int +slaunch_fixup_jump_vector(void) +{ + struct sl_ap_wake_info *ap_wake_info; + unsigned int *ap_jmp_ptr = 0; + + if (!atomic_dec_and_test(&first_ap_only)) + return 0; + + ap_wake_info = slaunch_get_ap_wake_info(); + + ap_jmp_ptr = (unsigned int *)__va(ap_wake_info->ap_wake_block + + ap_wake_info->ap_jmp_offset); + + *ap_jmp_ptr = real_mode_header->sl_trampoline_start32; + + pr_info("TXT AP long jump address updated\n"); + + return 0; +} + +/* + * TXT AP startup is quite different than normal. The APs cannot have #INIT + * asserted on them or receive SIPIs. The early Secure Launch code has parked + * the APs in a pause loop waiting to receive an NMI. This will wake the APs + * and have them jump to the protected mode code in the rmpiggy where the rest + * of the SMP boot of the AP will proceed normally. + */ +static int +slaunch_wakeup_cpu_from_txt(int cpu, int apicid) +{ + unsigned long send_status = 0, accept_status = 0; + + /* Only done once */ + if (slaunch_fixup_jump_vector()) + return -1; + + /* Send NMI IPI to idling AP and wake it up */ + apic_icr_write(APIC_DM_NMI, apicid); + + if (init_udelay == 0) + udelay(10); + else + udelay(300); + + send_status = safe_apic_wait_icr_idle(); + + if (init_udelay == 0) + udelay(10); + else + udelay(300); + + accept_status = (apic_read(APIC_ESR) & 0xEF); + + if (send_status) + pr_err("Secure Launch IPI never delivered???\n"); + if (accept_status) + pr_err("Secure Launch IPI delivery error (%lx)\n", + accept_status); + + return (send_status | accept_status); +} + +#else + +#define slaunch_wakeup_cpu_from_txt(cpu, apicid) 0 + +#endif /* !CONFIG_SECURE_LAUNCH */ + /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad * (ie clustered apic addressing mode), this is a LOGICAL apic ID. @@ -1071,6 +1149,12 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, cpumask_clear_cpu(cpu, cpu_initialized_mask); smp_mb(); + /* With Intel TXT, the AP startup is totally different */ + if (slaunch_get_flags() & (SL_FLAG_ACTIVE|SL_FLAG_ARCH_TXT)) { + boot_error = slaunch_wakeup_cpu_from_txt(cpu, apicid); + goto txt_wake; + } + /* * Wake up a CPU in difference cases: * - Use the method in the APIC driver if it's defined @@ -1083,6 +1167,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid, cpu0_nmi_registered); +txt_wake: + if (!boot_error) { /* * Wait 10s total for first sign of life from AP diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index af04512..7215040 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S @@ -33,6 +33,9 @@ SYM_DATA_START(real_mode_header) #ifdef CONFIG_X86_64 .long __KERNEL32_CS #endif +#ifdef CONFIG_SECURE_LAUNCH + .long pa_sl_trampoline_start32 +#endif SYM_DATA_END(real_mode_header) /* End signature, used to verify integrity */ diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S index 251758e..d5fb210 100644 --- a/arch/x86/realmode/rm/trampoline_64.S +++ b/arch/x86/realmode/rm/trampoline_64.S @@ -84,6 +84,43 @@ SYM_CODE_END(trampoline_start) .section ".text32","ax" .code32 +#ifdef CONFIG_SECURE_LAUNCH + .balign 4 +SYM_CODE_START(sl_trampoline_start32) + /* + * The early secure launch stub AP wakeup code has taken care of all + * the vagaries of launching out of TXT. This bit just mimics what the + * 16b entry code does and jumps off to the real startup_32. + */ + cli + wbinvd + + /* + * The %ebx provided is not terribly useful since it is the physical + * address of tb_trampoline_start and not the base of the image. + * Use pa_real_mode_base, which is fixed up, to get a run time + * base register to use for offsets to location that do not have + * pa_ symbols. + */ + movl $pa_real_mode_base, %ebx + + /* + * This may seem a little odd but this is what %esp would have had in + * it on the jmp from real mode because all real mode fixups were done + * via the code segment. The base is added at the 32b entry. + */ + movl rm_stack_end, %esp + + lgdt tr_gdt(%ebx) + lidt tr_idt(%ebx) + + movw $__KERNEL_DS, %dx # Data segment descriptor + + /* Jump to where the 16b code would have jumped */ + ljmpl $__KERNEL32_CS, $pa_startup_32 +SYM_CODE_END(sl_trampoline_start32) +#endif + .balign 4 SYM_CODE_START(startup_32) movl %edx, %ss -- 1.8.3.1