From patchwork Wed Jan 22 15:13:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Grimm X-Patchwork-Id: 1227322 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482pqm4dy8z9sR1 for ; Thu, 23 Jan 2020 02:15:16 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 482pqm3hB0zDqPC for ; Thu, 23 Jan 2020 02:15:16 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=grimm@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 482pqQ67cMzDqDT for ; Thu, 23 Jan 2020 02:14:52 +1100 (AEDT) Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00MFDsP5126716 for ; Wed, 22 Jan 2020 10:14:49 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 2xp5yf2ng5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 22 Jan 2020 10:14:48 -0500 Received: from m0098420.ppops.net (m0098420.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00MFE21M127433 for ; Wed, 22 Jan 2020 10:14:48 -0500 Received: from ppma04wdc.us.ibm.com (1a.90.2fa9.ip4.static.sl-reverse.com [169.47.144.26]) by mx0b-001b2d01.pphosted.com with ESMTP id 2xp5yf2nfk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 10:14:47 -0500 Received: from pps.filterd (ppma04wdc.us.ibm.com [127.0.0.1]) by ppma04wdc.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00MF9pZ5009164; Wed, 22 Jan 2020 15:14:47 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma04wdc.us.ibm.com with ESMTP id 2xksn6p434-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 15:14:47 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00MFEjKD47972626 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 22 Jan 2020 15:14:45 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1C5B2BE051; Wed, 22 Jan 2020 15:14:45 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EE41CBE04F; Wed, 22 Jan 2020 15:14:43 +0000 (GMT) Received: from alain.ibm.com (unknown [9.85.182.18]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 22 Jan 2020 15:14:43 +0000 (GMT) From: Ryan Grimm To: oohall@gmail.com Date: Wed, 22 Jan 2020 10:13:49 -0500 Message-Id: <20200122151354.23683-2-grimm@linux.ibm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200122151354.23683-1-grimm@linux.ibm.com> References: <20200122151354.23683-1-grimm@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-17_05:2020-01-16, 2020-01-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 clxscore=1011 priorityscore=1501 lowpriorityscore=0 phishscore=0 malwarescore=0 mlxscore=0 suspectscore=0 spamscore=0 bulkscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001220136 Subject: [Skiboot] [RFC PATCH v3 1/6] doc/opal-uv-api.rst X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: janani@us.ibm.com, suka@us.ibm.com, skiboot@lists.ozlabs.org Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Signed-off-by: Ryan Grimm --- doc/opal-uv-api.rst | 441 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 doc/opal-uv-api.rst diff --git a/doc/opal-uv-api.rst b/doc/opal-uv-api.rst new file mode 100644 index 00000000..5b49d79a --- /dev/null +++ b/doc/opal-uv-api.rst @@ -0,0 +1,441 @@ +.. SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +================= +OPAL UV API (RFC) +================= + +.. contents:: + :depth: 3 + +.. sectnum:: + :depth: 3 + +This document describes the function calling interface between OPAL +and the Ultravisor. + +Protected Execution Facility +############################ + +Protected Execution Facility (PEF) is an architectural change for +POWER 9 that enables Secure Virtual Machines (SVMs). When enabled, +PEF adds a new higher privileged mode, called Ultravisor mode, to +POWER architecture. Along with the new mode there is new firmware +called the Protected Execution Ultravisor (or Ultravisor for short). +Ultravisor mode is the highest privileged mode in POWER architecture. + ++------------------+ +| Privilege States | ++==================+ +| Problem | ++------------------+ +| Supervisor | ++------------------+ +| Hypervisor | ++------------------+ +| Ultravisor | ++------------------+ + +PEF protects SVMs from the hypervisor, privileged users, and other +VMs in the system. SVMs are protected while at rest and can only be +executed by an authorized machine. All virtual machines utilize +hypervisor services. The Ultravisor filters calls between the SVMs +and the hypervisor to assure that information does not accidentally +leak. All hypercalls except H_RANDOM are reflected to the hypervisor. +H_RANDOM is not reflected to prevent the hypervisor from influencing +random values in the SVM. + +To support this there is a refactoring of the ownership of resources +in the CPU. Some of the resources which were previously hypervisor +privileged are now ultravisor privileged. + +Hardware +======== + +The hardware changes include the following: + +* There is a new bit in the MSR that determines whether the current + process is running in secure mode, MSR(S) bit 41. MSR(S)=1, process + is in secure mode, MSR(s)=0 process is in normal mode. + +* The MSR(S) bit can only be set by the Ultravisor. + +* HRFID cannot be used to set the MSR(S) bit. If the hypervisor needs + to return to a SVM it must use an ultracall. It can determine if + the VM it is returning to is secure. + +* There is a new Ultravisor privileged register, SMFCTRL, which has an + enable/disable bit SMFCTRL(E). + +* The privilege of a process is now determined by three MSR bits, + MSR(S, HV, PR). In each of the tables below the modes are listed + from least privilege to highest privilege. The higher privilege + modes can access all the resources of the lower privilege modes. + +**Secure Mode MSR Settings** + ++---+---+---+---------------+ +| S | HV| PR|Privilege | ++===+===+===+===============+ +| 1 | 0 | 1 | Problem | ++---+---+---+---------------+ +| 1 | 0 | 0 | Privileged(OS)| ++---+---+---+---------------+ +| 1 | 1 | 0 | Ultravisor | ++---+---+---+---------------+ +| 1 | 1 | 1 | Reserved | ++---+---+---+---------------+ + +**Normal Mode MSR Settings** + ++---+---+---+---------------+ +| S | HV| PR|Privilege | ++===+===+===+===============+ +| 0 | 0 | 1 | Problem | ++---+---+---+---------------+ +| 0 | 0 | 0 | Privileged(OS)| ++---+---+---+---------------+ +| 0 | 1 | 0 | Hypervisor | ++---+---+---+---------------+ +| 0 | 1 | 1 | Problem (HV) | ++---+---+---+---------------+ + +* Memory is partitioned into secure and normal memory. Only processes + that are running in secure mode can access secure memory. + +* The hardware does not allow anything that is not running secure to + access secure memory. This means that the Hypervisor cannot access + the memory of the SVM without using an ultracall (asking the + Ultravisor). The Ultravisor will only allow the hypervisor to see + the SVM memory encrypted. + +* I/O systems are not allowed to directly address secure memory. This + limits the SVMs to virtual I/O only. + +* The architecture allows the SVM to share pages of memory with the + hypervisor that are not protected with encryption. However, this + sharing must be initiated by the SVM. + +* When a process is running in secure mode all hypercalls + (syscall lev=1) are reflected to the Ultravisor. + +* When a process is in secure mode all interrupts go to the + Ultravisor. + +* The following resources have become Ultravisor privileged and + require an Ultravisor interface to manipulate: + + * Processor configurations registers (SCOMs). + + * Stop state information. + + * The debug registers CIABR, DAWR, and DAWRX become Ultravisor + resources when SMFCTRL(D) is set. If SMFCTRL(D) is not set they do + not work in secure mode. When set, reading and writing requires + an Ultravisor call, otherwise that will cause a Hypervisor Emulation + Assistance interrupt. + + * PTCR and partition table entries (partition table is in secure + memory). An attempt to write to PTCR will cause a Hypervisor + Emulation Assitance interrupt. + + * LDBAR (LD Base Address Register) and IMC (In-Memory Collection) + non-architected registers. An attempt to write to them will cause a + Hypervisor Emulation Assistance interrupt. + + * Paging for an SVM, sharing of memory with Hypervisor for an SVM. + (Including Virtual Processor Area (VPA) and virtual I/O). + +Software/Microcode +================== + +The software changes include: + +* When the UV_ESM ultracall is made the Ultravisor copies the VM into + secure memory, decrypts the verification information, and checks the + integrity of the SVM. If the integrity check passes the Ultravisor + passes control in secure mode. + +The Ultravisor offers new services to the hypervisor and SVMs. These +are accessed through ultracalls. + +Terminology +=========== + +* Hypercalls: special system calls used to request services from + Hypervisor. + +* Normal memory: Memory that is accessible to Hypervisor. + +* Normal page: Page backed by normal memory and available to + Hypervisor. + +* Secure memory: Memory that is accessible only to Ultravisor and + SVMs. + +* Secure page: Page backed by secure memory and only available to + Ultravisor and SVM. + +* SVM: Secure Virtual Machine. + +* Ultracalls: special system calls used to request services from + Ultravisor. + +Ultravisor Initialization +######################### + +Secure Memory +============= + +Skiboot parses secure memory from the HDAT tables and creates the secure-memory +device tree node, similar to a memory@ node except the device_type is +"secure_memory". For example: + +.. code-block:: dts + + secure-memory@100fe00000000 { + device_type = "secure_memory"; + compatible = "ibm,secure_memory"; + ibm,chip-id = <0>; + reg = < 0x100fe 0x0 0x2 0x0>; + } + +Regions of secure memory will be reserved by hostboot such as OCC, HOMER, and +SBE. Skiboot will use the existing reserve infrastructure to reserve them. +For example: + +.. code-block:: + + ibm,HCODE@100fffcaf0000 + ibm,OCC@100fffcdd0000 + ibm,RINGOVD@100fffcae0000 + ibm,WOFDATA@100fffcb90000 + ibm,arch-reg-data@100fffd700000 + ibm,hbrt-code-image@100fffcec0000 + ibm,hbrt-data@100fffd420000 + ibm,homer-image@100fffd800000 + ibm,homer-image@100fffdc00000 + ibm,occ-common-area@100ffff800000 + ibm,sbe-comm@100fffce90000 + ibm,sbe-comm@100fffceb0000 + ibm,sbe-ffdc@100fffce80000 + ibm,sbe-ffdc@100fffcea0000 + ibm,secure-crypt-algo-code@100fffce70000 + ibm,uvbwlist@100fffcad0000 + +For Mambo, ultra.tcl creates the secure-memory device tree node and is +currently defined at 8GB with size 8GB. Mambo has no protection on secure +memory, so a watchpoint could be used to ensure Skiboot does not touch secure +memory. + +For BML, the BML script parses secure memory from the Cronus config file and +creates the secure-memory device tree node. + +In all cases, the console log should indicate secure memory has been found and +added to the device tree. For example: + +.. code-block:: + + [ 68.235326307,5] UV: Secure memory range added to DT [0x0001000e00000000..0x001001000000000] + +Loading The Ultravisor +====================== + +Skiboot uses secure and trusted boot to load and verify the compressed UV image +from the PNOR into regular memory. It unpacks the UV into regular memory in +the function ``init_uv``. + +``init_uv`` finds the UV node in the device tree via the "ibm,ultravisor" +compatible property. For example: + +.. code-block:: dts + + ibm,ultravisor { + compatible = "ibm,ultravisor"; + #address-cells = <0x02>; + #size-cells = <0x01>; + + firmware@200000000 { + compatible = "ibm,uv-firmware"; + reg = <0x02 0x00 0xf677f>; + memcons = <0x00 0x3022d030>; + sys-fdt = <0x00 0x30509068>; + uv-fdt = <0x02 0x200000>; + }; + }; + +In the case of Mambo or BML, skiboot does not load the UV from the PNOR, so the +proprety reg must be provided so skiboot knows where to copy the UV image from, +like the example above. + +Otherwise, on Hostboot, skiboot creates the reg property which it uses to start +the UV. + +``init_uv`` parses secure memory ranges and copies the UV into the start of the +first available secure range. + +Starting The Ultravisor +======================= + +Skiboot starts the UV in ``main_cpu_entry`` before the kernel is loaded and booted. +Skiboot creates a job on all threads and sends them to ``start_uv`` in asm/head.S. +This function's prototype is: + +.. code-block:: c + + /** + * @brief Start UV. + * + * @param uv_load_addr Load address of ultravisor. + * @param uv_opal Pointer to uv_opal strucutre. + * + * @return 0 on success, else a negative error code on failure. + */ + u64 start_uv(u64 uv_load_addr, struct uv_opal *uv_opal); + +The opal ultravisor abi, defined in ``struct uv_opal``, allows passing configuration +information to the UV and obtaining a return code from the ultravisor post +initialization. It is defined as: + +.. code-block:: c + + struct uv_opal { + __be32 magic; /**< 'OPUV' 0x4F505556 OPUV_MAGIC */ + __be32 version; /**< uv_opal struct version */ + __be32 uv_api_ver; /**< Current uv api version. */ + __be64 uv_base_addr; /**< Base address of UV in secure memory. */ + __be64 sys_fdt; /**< System FDT. */ + __be64 uv_fdt; /**< UV FDT in secure memory. */ + __be64 uv_mem; /**< struct memcons */ + }; + +The ``uv_fdt`` is constructed in secure memory. It is allocated after the +ultravisor image at ``uv_base_addr + UV_LOAD_MAX_SIZE``. This allows the +ultravisor to load at start of the first secure memory range and recover the +memory allocated to ``uv_fdt``. + +.. code-block:: dts + + ibm,uv-fdt { + compatible = "ibm,uv-fdt"; + wrapping-key-password = "gUMShz6l2x4O9IeHrvBSuBR0FYANZTYK"; + }; + +The UV parses ``sys_fdt``, creates internal structures, and threads return in +hypervisor privilege mode and 0 in ``uv_ret_code``. + +If successful, skiboot sets a variable named ``uv_present`` to true. Skiboot uses +the macro ``is_uv_present`` to dermine if the UV is initialized and ready to +perform ucalls. + +uv_base_addr is not needed by the UV but is used by ``cpu_start_ultravisor``. This +member could be moved into a separate structure for ``cpu_start_ultravisor``. + +Ultravisor Failed Start Recovery +================================ + +If the ultravisor fails to start it will return a error code to init_uv. +init_uv will print error messages to the skiboot log and attempt to free +structures associated with the ultravisor. + +Skiboot will continue to be in ultravisor privilege mode, and will need to +perform a recovery action. + +[**TODO**: Need to describe the steps for Ultravisor load failure recovery action.] + +Ultracalls +########## + +Ultravisor calls API +==================== + +This section describes Ultravisor calls (ultracalls) needed by skiboot. +The ultracalls allow the skiboot to request services from the +Ultravisor such as initializing a chip unit via XSCOM. + +The specific service needed from an ultracall is specified in register +R3 (the first parameter to the ultracall). Other parameters to the +ultracall, if any, are specified in registers R4 through R12. + +Return value of all ultracalls is in register R3. Other output values +from the ultracall, if any, are returned in registers R4 through R12. + +Each ultracall returns specific error codes, applicable in the context +of the ultracall. However, like with the PowerPC Architecture Platform +Reference (PAPR), if no specific error code is defined for a +particular situation, then the ultracall will fallback to an erroneous +parameter-position based code. i.e U_PARAMETER, U_P2, U_P3 etc +depending on the ultracall parameter that may have caused the error. + +For now this only covers ultracalls currently implemented and being used by +skiboot but others can be added here when it makes sense. + +The full specification for all ultracalls will eventually be made available in +the public/OpenPower version of the PAPR specification. + +Ultracalls used by Skiboot +========================== + +UV_READ_SCOM +------------ + +Perform an XSCOM read and put the value in a buffer. + +Syntax +~~~~~~ + +.. code-block:: c + + long ucall(unsigned long UV_READ_SCOM, + unsigned long *retbuf, + u64 partid, + u64 pcb_addr) + +Return values +~~~~~~~~~~~~~ + +* U_SUCCESS on success. +* U_PERMISSION if called from VM context. +* U_PARAMETER if invalid partiton or address. +* U_BUSY if unit is busy, need to retry. +* U_XSCOM_CHIPLET_OFF if cpu is asleep. +* U_XSCOM_PARTIAL_GOOD if partial good. +* U_XSCOM_ADDR_ERROR if address error. +* U_XSCOM_CLOCK_ERROR if clock error. +* U_XSCOM_PARITY_ERROR if parity error. +* U_XSCOM_TIMEOUT if timeout. + +UV_WRITE_SCOM +------------- + +Perform an XSCOM write. + +Syntax +~~~~~~ + +.. code-block:: c + + long ucall(unsigned long UV_WRITE_SCOM, + u64 partid, + u64 pcb_addr, + u64 val) + +Return values +~~~~~~~~~~~~~ + +One of the following values: + +* U_SUCCESS on success. +* U_PERMISSION if called from VM context. +* U_PARAMETER if invalid partiton. +* U_BUSY if unit is busy, need to retry. +* U_XSCOM_CHIPLET_OFF if cpu is asleep. +* U_XSCOM_PARTIAL_GOOD if partial good. +* U_XSCOM_ADDR_ERROR if address error. +* U_XSCOM_CLOCK_ERROR if clock error. +* U_XSCOM_PARITY_ERROR if parity error. +* U_XSCOM_TIMEOUT if timeout. + +References +########## + +.. [1] `Supporting Protected Computing on IBM Power Architecture `_ From patchwork Wed Jan 22 15:13:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Grimm X-Patchwork-Id: 1227323 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482prG2XC6z9sR1 for ; Thu, 23 Jan 2020 02:15:42 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 482prG1cSyzDqPF for ; Thu, 23 Jan 2020 02:15:42 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=grimm@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 482pr06ZH1zDqNg for ; Thu, 23 Jan 2020 02:15:28 +1100 (AEDT) Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00MFEgKQ101586 for ; Wed, 22 Jan 2020 10:15:26 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 2xnnn7rqx3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 22 Jan 2020 10:15:24 -0500 Received: from m0098413.ppops.net (m0098413.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00MFExdh102754 for ; Wed, 22 Jan 2020 10:15:24 -0500 Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0b-001b2d01.pphosted.com with ESMTP id 2xnnn7rqwv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 10:15:24 -0500 Received: from pps.filterd (ppma03wdc.us.ibm.com [127.0.0.1]) by ppma03wdc.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00MF9rU5008405; Wed, 22 Jan 2020 15:15:23 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma03wdc.us.ibm.com with ESMTP id 2xksn6e3nv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 15:15:23 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00MFFKSp57540900 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 22 Jan 2020 15:15:20 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A53FBBE051; Wed, 22 Jan 2020 15:15:20 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 91E5CBE054; Wed, 22 Jan 2020 15:15:19 +0000 (GMT) Received: from alain.ibm.com (unknown [9.85.182.18]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 22 Jan 2020 15:15:19 +0000 (GMT) From: Ryan Grimm To: oohall@gmail.com Date: Wed, 22 Jan 2020 10:13:50 -0500 Message-Id: <20200122151354.23683-3-grimm@linux.ibm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200122151354.23683-1-grimm@linux.ibm.com> References: <20200122151354.23683-1-grimm@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-17_05:2020-01-16, 2020-01-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 mlxlogscore=999 spamscore=0 impostorscore=0 phishscore=0 priorityscore=1501 bulkscore=0 suspectscore=3 lowpriorityscore=0 clxscore=1015 mlxscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001220136 Subject: [Skiboot] [RFC PATCH v3 2/6] Add ultravisor support in OPAL X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: janani@us.ibm.com, suka@us.ibm.com, skiboot@lists.ozlabs.org Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Ultravisor is the firmware which runs in the new priveleged mode called ultravisor mode, which was introduced in Power 9. Ultravisor enables running of secure virtual machines on the host. Protected execution facility in Power 9 uses special memory areas designated as secure memory, which can be accessed only in the ultravisor mode. This protection is provided by the hardware. These designated memory areas are used by the guests running as secure virtual machines. The secure memory ranges are provided by the hostboot through HDAT. Skiboot parses HDAT and creates secure-memory@ device tree nodes. Ultravisor firmware is present as a compressed lid file or as 'UVISOR' partition. Skiboot uses the resource load helper and xz decompress to load and decompress the ultravisor firmware into secure memory on chip 0. The ultravisor image is started on each CPU and the CPUs return with MSR S bit off. For Mambo, ultra.tcl creates the secure-memory-ranges property at 8GB. Mambo has no protection on secure memory, so a watchpoint should be used to ensure Skiboot does not touch secure memory. ultra.tcl creates the ibm,secure-mem reserve. For BML, the BML script parses secure memory from the Cronus config file and creates the secure-memory-ranges proprty. A new type of system call called the ultra call is used to get the services of the ultravisor. This ultracall support is needed in skiboot to access the xscoms which are in the secure memory area. For more details, see doc/opal-uv-api.rst. Signed-off-by: Ryan Grimm [ maddy: Initial implementation] [ maddy: ultra-call support for skiboot ] Signed-off-by: Madhavan Srinivasan [ santosh: Initial implementation] [ santosh: ultra-call support for skiboot ] Signed-off-by: Santosh Sivaraj [ andmike: Split init and start of ultravisor ] [ andmike: ABI change to switch from r0 to r3 ] [ andmike: Remove stb header prior to decompress ] [ andmike: Pickup wrapkey data from mambo ] Signed-off-by: Michael Anderson [ cclaudio: Fix compilation for GCC9 ] Signed-off-by: Claudio Carvalho [ linuxram: populate the UV FDT after the password is generated ] Signed-off-by: Ram Pai --- asm/head.S | 54 +++++ core/flash.c | 1 + core/init.c | 11 + core/mem_region.c | 32 +++ hdata/memory.c | 23 ++- hdata/test/hdata_to_dt.c | 1 + hw/Makefile.inc | 1 + hw/fsp/fsp.c | 2 + hw/ultravisor.c | 395 ++++++++++++++++++++++++++++++++++++ include/mem_region-malloc.h | 3 + include/platform.h | 1 + include/processor.h | 12 ++ include/ultravisor-api.h | 19 ++ include/ultravisor.h | 27 +++ 14 files changed, 576 insertions(+), 6 deletions(-) create mode 100644 hw/ultravisor.c create mode 100644 include/ultravisor-api.h create mode 100644 include/ultravisor.h diff --git a/asm/head.S b/asm/head.S index b565f6c9..49a62ce5 100644 --- a/asm/head.S +++ b/asm/head.S @@ -1039,3 +1039,57 @@ start_kernel_secondary: mtspr SPR_HSRR1,%r10 mfspr %r3,SPR_PIR hrfid + +/* start_uv register usage: + * + * r3 is base address of UV + * r4 is ptr to struct uv_opal + */ +.global start_uv +start_uv: + mflr %r0 + std %r0,16(%r1) + sync + icbi 0,%r3 + sync + isync + mtctr %r3 + mr %r3,%r4 + LOAD_IMM64(%r8,SKIBOOT_BASE); + LOAD_IMM32(%r10, opal_entry - __head) + add %r9,%r8,%r10 + LOAD_IMM32(%r6, EPAPR_MAGIC) + addi %r7,%r5,1 + li %r4,0 + li %r5,0 + bctrl /* branch to UV here */ + ld %r0,16(%r1) + mtlr %r0 + blr + +.global ucall +ucall: + mflr %r0 + stdu %r1,-STACK_FRAMESIZE(%r1) + std %r0,STACK_LR(%r1) + mfcr %r0 + stw %r0,STACK_CR(%r1) + std %r4,STACK_GPR4(%r1) /* Save ret buffer */ + mr %r4,%r5 + mr %r5,%r6 + mr %r6,%r7 + mr %r7,%r8 + mr %r8,%r9 + mr %r9,%r10 + sc 2 /* invoke the ultravisor */ + ld %r12,STACK_GPR4(%r1) + std %r4, 0(%r12) + std %r5, 8(%r12) + std %r6, 16(%r12) + std %r7, 24(%r12) + lwz %r0,STACK_CR(%r1) + mtcrf 0xff,%r0 + ld %r0,STACK_LR(%r1) + mtlr %r0 + addi %r1,%r1,STACK_FRAMESIZE + blr /* return r3 = status */ diff --git a/core/flash.c b/core/flash.c index de748641..247aec5c 100644 --- a/core/flash.c +++ b/core/flash.c @@ -45,6 +45,7 @@ static struct { { RESOURCE_ID_INITRAMFS,RESOURCE_SUBID_NONE, "ROOTFS" }, { RESOURCE_ID_CAPP, RESOURCE_SUBID_SUPPORTED, "CAPP" }, { RESOURCE_ID_IMA_CATALOG, RESOURCE_SUBID_SUPPORTED, "IMA_CATALOG" }, + { RESOURCE_ID_UV_IMAGE, RESOURCE_SUBID_NONE, "UVISOR" }, { RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE, "VERSION" }, { RESOURCE_ID_KERNEL_FW, RESOURCE_SUBID_NONE, "BOOTKERNFW" }, }; diff --git a/core/init.c b/core/init.c index 339462e5..4160e68d 100644 --- a/core/init.c +++ b/core/init.c @@ -46,6 +46,7 @@ #include #include #include +#include enum proc_gen proc_gen; unsigned int pcie_max_link_speed; @@ -558,6 +559,8 @@ void __noreturn load_and_boot_kernel(bool is_reboot) trustedboot_exit_boot_services(); + start_ultravisor(); + ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT); @@ -1296,6 +1299,11 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt) pci_nvram_init(); preload_capp_ucode(); + + /* preload and decompress ultravisor image */ + uv_preload_image(); + uv_decompress_image(); + start_preload_kernel(); /* Catalog decompression routine */ @@ -1354,6 +1362,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt) /* Add the list of interrupts going to OPAL */ add_opal_interrupts(); + /* Init ultravisor software */ + init_uv(); + /* Now release parts of memory nodes we haven't used ourselves... */ mem_region_release_unused(); diff --git a/core/mem_region.c b/core/mem_region.c index eb48a1a1..91bfa1f1 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -851,6 +851,38 @@ static bool matches_chip_id(const __be32 ids[], size_t num, u32 chip_id) return false; } +void __local_free(void *p, const char *location) +{ + struct mem_region *region; + struct alloc_hdr *hdr; + + if (!p) + return; + + lock(&mem_region_lock); + + list_for_each(®ions, region, list) { + /* localr_alloc doesn't use heap */ + if (region == &skiboot_heap) + continue; + + if (p >= region_start(region) && + (p < (region_start(region) + region->len))) { + hdr = p - sizeof(*hdr); + + if (hdr->free) + bad_header(region, hdr, "re-freed", location); + + lock(®ion->free_list_lock); + make_free(region, (struct free_hdr *)hdr, location, false); + unlock(®ion->free_list_lock); + } + + } + + unlock(&mem_region_lock); +} + void *__local_alloc(unsigned int chip_id, size_t size, size_t align, const char *location) { diff --git a/hdata/memory.c b/hdata/memory.c index 9c588ff6..99d54298 100644 --- a/hdata/memory.c +++ b/hdata/memory.c @@ -32,7 +32,7 @@ struct HDIF_ms_area_address_range { __be64 start; __be64 end; __be32 chip; - __be32 mirror_attr; + __be32 memory_attr; __be64 mirror_start; __be32 controller_id; __be32 phys_attr; @@ -59,6 +59,9 @@ struct HDIF_ms_area_address_range { #define MS_CONTROLLER_MCS_ID(id) GETFIELD(PPC_BITMASK32(4, 7), id) #define MS_CONTROLLER_MCA_ID(id) GETFIELD(PPC_BITMASK32(8, 15), id) +#define MS_ATTR_PEF (PPC_BIT32(23)) +#define UV_SECURE_MEM_BIT (PPC_BIT(15)) + struct HDIF_ms_area_id { __be16 id; #define MS_PTYPE_RISER_CARD 0x8000 @@ -128,11 +131,11 @@ static bool add_address_range(struct dt_node *root, chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip)); - prlog(PR_DEBUG, " Range: 0x%016llx..0x%016llx " - "on Chip 0x%x mattr: 0x%x pattr: 0x%x status:0x%x\n", + prlog(PR_INFO, " Range: 0x%016llx..0x%016llx " + "on Chip 0x%x memattr: 0x%08x pattr: 0x%x status:0x%x\n", (long long)be64_to_cpu(arange->start), (long long)be64_to_cpu(arange->end), - chip_id, be32_to_cpu(arange->mirror_attr), + chip_id, be32_to_cpu(arange->memory_attr), mem_type, mem_status); /* reg contains start and length */ @@ -161,6 +164,13 @@ static bool add_address_range(struct dt_node *root, return false; } + if (be32_to_cpu(arange->memory_attr) & MS_ATTR_PEF) { + prlog(PR_DEBUG, "HDAT: Found secure memory\n"); + name = "secure-memory"; + dev_type = "secure-memory"; + compat = "ibm,secure-memory"; + } + if (be16_to_cpu(id->flags) & MS_AREA_SHARED) { mem = dt_find_by_name_addr(dt_root, name, reg[0]); if (mem) { @@ -674,9 +684,10 @@ static void get_hb_reserved_mem(struct HDIF_common_hdr *ms_vpd) /* * Workaround broken HDAT reserve regions which are - * bigger than 512MB + * bigger than 512MB and not secure memory */ - if ((end_addr - start_addr) > 0x20000000) { + if (((end_addr - start_addr) > 0x20000000) && + !(start_addr & UV_SECURE_MEM_BIT)) { prlog(PR_ERR, "MEM: Ignoring Bad HDAT reserve: too big\n"); continue; } diff --git a/hdata/test/hdata_to_dt.c b/hdata/test/hdata_to_dt.c index 11b7a3ac..d487e272 100644 --- a/hdata/test/hdata_to_dt.c +++ b/hdata/test/hdata_to_dt.c @@ -64,6 +64,7 @@ unsigned long tb_hz = 512000000; #define PVR_P8NVL 0x004c0100 #define PVR_P9 0x004e0200 #define PVR_P9P 0x004f0100 +#define MSR_S PPC_BIT(41) /* Secure Mode enable */ #define SPR_PVR 0x11f /* RO: Processor version register */ diff --git a/hw/Makefile.inc b/hw/Makefile.inc index b708bdfe..848898b9 100644 --- a/hw/Makefile.inc +++ b/hw/Makefile.inc @@ -9,6 +9,7 @@ HW_OBJS += fake-nvram.o lpc-mbox.o npu2.o npu2-hw-procedures.o HW_OBJS += npu2-common.o npu2-opencapi.o phys-map.o sbe-p9.o capp.o HW_OBJS += occ-sensor.o vas.o sbe-p8.o dio-p9.o lpc-port80h.o cache-p9.o HW_OBJS += npu-opal.o npu3.o npu3-nvlink.o npu3-hw-procedures.o +HW_OBJS += ultravisor.o HW=hw/built-in.a include $(SRC)/hw/fsp/Makefile.inc diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c index 7592ee07..0411f035 100644 --- a/hw/fsp/fsp.c +++ b/hw/fsp/fsp.c @@ -114,6 +114,7 @@ static u64 fsp_hir_timeout; #define KERNEL_LID_PHYP 0x80a00701 #define KERNEL_LID_OPAL 0x80f00101 #define INITRAMFS_LID_OPAL 0x80f00102 +#define ULTRA_LID_OPAL 0x80f00105 /* * We keep track on last logged values for some things to print only on @@ -2372,6 +2373,7 @@ static struct { } fsp_lid_map[] = { { RESOURCE_ID_KERNEL, RESOURCE_SUBID_NONE, KERNEL_LID_OPAL }, { RESOURCE_ID_INITRAMFS,RESOURCE_SUBID_NONE, INITRAMFS_LID_OPAL }, + { RESOURCE_ID_UV_IMAGE, RESOURCE_SUBID_NONE, ULTRA_LID_OPAL }, { RESOURCE_ID_IMA_CATALOG,IMA_CATALOG_NIMBUS, 0x80f00103 }, { RESOURCE_ID_CAPP, CAPP_IDX_MURANO_DD20, 0x80a02002 }, { RESOURCE_ID_CAPP, CAPP_IDX_MURANO_DD21, 0x80a02001 }, diff --git a/hw/ultravisor.c b/hw/ultravisor.c new file mode 100644 index 00000000..4222f212 --- /dev/null +++ b/hw/ultravisor.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2018-2019 IBM Corp. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *uv_image = NULL; +static size_t uv_image_size; +struct xz_decompress *uv_xz = NULL; +static struct uv_opal *uv_opal; + +const char * wrap_key_prop_str[] = { + "wrapping-key-passwd", + "wrapping-key-publicname", + "wrapping-key-policy-a", + "wrapping-key-policy-b", + NULL +}; + +static void create_uv_fw_node(struct dt_node *uv_node, uint64_t addr, uint32_t size) { + struct dt_node *uv_fw_node; + char fw_name[64]; + + snprintf(fw_name, 64, "firmware@%llx", addr); + uv_fw_node = dt_new_check(uv_node, fw_name); + dt_add_property_string(uv_fw_node, "compatible", "ibm,uv-firmware"); + dt_add_property_cells(uv_fw_node, "reg", addr >> 32, addr & 0xfffffff, size); +} + +static uint64_t find_secure_mem(void) +{ + struct dt_node *node; + const struct dt_property *reg; + uint64_t secure_mem; + + dt_for_each_compatible(dt_root, node, "ibm,secure-memory") + if (dt_get_chip_id(node) == 0) + break; + + reg = dt_find_property(node, "reg"); + secure_mem = dt_get_number(reg->prop, 2); + + return secure_mem; +} + +static struct dt_node *add_uv_dt_node(void) +{ + struct dt_node *uv_node; + uint64_t uv_fw_start; + + uv_node = dt_new_check(dt_root, "ibm,ultravisor"); + dt_add_property_string(uv_node, "compatible", "ibm,ultravisor"); + dt_add_property_cells(uv_node, "#address-cells", 2); + dt_add_property_cells(uv_node, "#size-cells", 1); + + uv_fw_start = find_secure_mem(); + create_uv_fw_node(uv_node, uv_fw_start, UV_LOAD_MAX_SIZE); + return uv_node; +} + +static struct dt_node *find_tpm_sim_node(void) +{ + struct dt_node *tpm_sim_node; + + tpm_sim_node = dt_find_compatible_node(dt_root, NULL, "uv,tpm_sim"); + if (!tpm_sim_node) { + prlog(PR_INFO, "uv,tpm_sim compatible node not found\n"); + return NULL; + } + + return tpm_sim_node; +} + +/* create ibm,ultravisor node if it does not exist. Mambo and BML pass it in. + * For HB, hdata/memory.c code parses HDAT and creates secure-memory nodes and + * find_secure_mem will return the reg property */ +static struct dt_node *get_uv_fw_node(void) +{ + struct dt_node *uv_fw_node; + + uv_fw_node = dt_find_compatible_node(dt_root, NULL, "ibm,uv-firmware"); + if (!uv_fw_node) { + prlog(PR_DEBUG, "UV: ibm,uv-firmware compatible node not found, creating\n"); + add_uv_dt_node(); + uv_fw_node = dt_find_compatible_node(dt_root, NULL, "ibm,uv-firmware"); + } + + return uv_fw_node; +} + +static bool get_uv_fw_region(uint64_t *addr, uint32_t *size) +{ + struct dt_node *node; + const struct dt_property *reg; + + node = get_uv_fw_node(); + + reg = dt_find_property(node, "reg"); + *addr = dt_get_number(reg->prop, 2); + *size = dt_get_number(reg->prop + sizeof(u64), 1); + + return true; +} + +static void update_uv_fw_node(uint64_t addr, uint32_t size) +{ + struct dt_node *uv_node, *uv_fw_node; + + if (!(uv_fw_node = dt_find_compatible_node(dt_root, NULL, "ibm,uv-firmware"))) { + prerror("UV: No ibm,uv-firmware node found\n"); + return; + } + + uv_node = uv_fw_node->parent; + dt_free(uv_fw_node); + create_uv_fw_node(uv_node, addr, size); +} + +static int add_wrapping_key_mambo(void *fdt) +{ + struct dt_node *tpm_sim_node; + const struct dt_property *property = NULL; + + if ((tpm_sim_node = find_tpm_sim_node())) { + int i; + + fdt_begin_node(fdt, "ibm,uv-tpm"); + fdt_property_string(fdt, "compatible", "ibm,uv-tpm"); + + for (i = 0; wrap_key_prop_str[i] != NULL; i++) { + property = dt_find_property(tpm_sim_node, + wrap_key_prop_str[i]); + if (property) { + fdt_property(fdt, wrap_key_prop_str[i], + property->prop, + property->len); + } + } + + fdt_end_node(fdt); + } + + return 0; +} + +static int fdt_add_wrapping_key(void *fdt) +{ + return add_wrapping_key_mambo(fdt); +} + +static int create_dtb_uv(void *uv_fdt) +{ + if (fdt_create(uv_fdt, UV_FDT_MAX_SIZE)) { + prerror("UV: Failed to create uv_fdt\n"); + return 1; + } + + fdt_finish_reservemap(uv_fdt); + fdt_begin_node(uv_fdt, ""); + fdt_property_string(uv_fdt, "description", "Ultravisor fdt"); + fdt_begin_node(uv_fdt, "ibm,uv-fdt"); + fdt_property_string(uv_fdt, "compatible", "ibm,uv-fdt"); + if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS) { + if (add_wrapping_key_mambo(uv_fdt)) + prlog(PR_ERR, "Failed to add the mambo wrapping key" + " to dt\n"); + } else + if (fdt_add_wrapping_key(uv_fdt)) + prlog(PR_ERR, "Failed to add the wrapping key" + " to dt\n"); + fdt_end_node(uv_fdt); + fdt_end_node(uv_fdt); + fdt_finish(uv_fdt); + + return OPAL_SUCCESS; +} + +static void cpu_start_ultravisor(void *data) +{ + struct uv_opal *ptr = (struct uv_opal *)data; + start_uv(ptr->uv_base_addr, ptr); +} + +int start_ultravisor(void) +{ + struct cpu_thread *cpu; + struct cpu_job **jobs; + uint64_t uv_fdt_addr; + uint64_t addr; + uint32_t size; + struct dt_node *uv_fw_node; + int i = 0; + + /* init_uv should have made the ibm,ultravisor node by now so don't + * start if something went wrong */ + if (!dt_find_compatible_node(dt_root, NULL, "ibm,ultravisor")) { + prlog(PR_DEBUG, "UV: No ibm,ultravisor found, won't start ultravisor\n"); + return OPAL_HARDWARE; + } + + get_uv_fw_region(&addr, &size); + + uv_fdt_addr = addr + UV_LOAD_MAX_SIZE; + + if (create_dtb_uv((void *)uv_fdt_addr)) + return OPAL_NO_MEM; + + uv_fw_node = get_uv_fw_node(); + + dt_add_property_u64s(uv_fw_node, "uv-fdt", uv_fdt_addr); + + uv_opal->uv_fdt = (__be64)uv_fdt_addr; + + prlog(PR_NOTICE, "UV: Starting Ultravisor at 0x%llx sys_fdt 0x%llx uv_fdt 0x%0llx\n", + addr, uv_opal->sys_fdt, uv_opal->uv_fdt); + + if (!addr || !uv_opal->sys_fdt || !uv_opal->uv_fdt) { + prerror("UV: Bad ptrs, not starting\n"); + return OPAL_INTERNAL_ERROR; + } + + jobs = zalloc(sizeof(struct cpu_job*) * cpu_max_pir); + + for_each_available_cpu(cpu) { + if (cpu == this_cpu()) + continue; + jobs[i++] = cpu_queue_job(cpu, "start_ultravisor", + cpu_start_ultravisor, (void *)uv_opal); + } + + cpu_start_ultravisor((void *)uv_opal); + + while (i > 0) + cpu_wait_job(jobs[--i], true); + + free(jobs); + + return OPAL_SUCCESS; +} + +static bool alloc_uv(void) +{ + struct proc_chip *chip = next_chip(NULL); + + uv_image_size = MAX_COMPRESSED_UV_IMAGE_SIZE; + if (!(uv_image = local_alloc(chip->id, uv_image_size, uv_image_size))) + return false; + memset(uv_image, 0, uv_image_size); + return true; +} + +static int tpm_nv_init(void) +{ + prlog(PR_INFO, "%s begin\n", __func__); + return 0; +} + +/* For HB, check for uv_xz != NULL and wait for decompress. UV should have + * been loaded from PNOR or FSP and decompressed earlier via uv_preload_image + * and uv_decompress_image. The secure location of the UV provided by those + * functions is in the xz struct. + * + * If uv_xz == NULL, Mambo and BML are expected to provide the source address + * in the device tree. Cronus can't use putmemdma to secure memory (or secure + * memory might be inaccessible to Cronus) so Skiboot copies the UV image from + * insecure memory to secure and updates the device tree. + */ +void init_uv() +{ + struct dt_node *uv_fw_node; + uint64_t uv_dt_src, uv_dt_reg, sys_fdt_addr; + uint32_t uv_fw_sz; + + prlog(PR_DEBUG, "UV: Init starting\n"); + + if (!is_msr_bit_set(MSR_S)) { + prlog(PR_DEBUG, "UV: S bit not set\n"); + return; + } + + if (!(uv_fw_node = get_uv_fw_node())) { + prerror("UV: ibm,uv-firmware node creation failed\n"); + return; + } + + uv_opal = local_alloc(this_cpu()->chip_id, sizeof(struct uv_opal), 8); + + tpm_nv_init(); + + get_uv_fw_region(&uv_dt_reg, &uv_fw_sz); + + if (uv_xz) { + /* Hostboot path */ + wait_xz_decompress(uv_xz); + if (uv_xz->status) { + prerror("UV: Compressed Ultravisor image failed to decompress\n"); + local_free(uv_xz); + local_free(uv_opal); + return; + } + local_free(uv_xz); + } else { + prlog(PR_INFO, "UV: Platform load failed. You're using Mambo or Cronus.\n"); + /* use addr provided by reg as source and update with secure memory */ + uv_dt_src = uv_dt_reg; + uv_dt_reg = find_secure_mem(); + prlog(PR_INFO, "UV: Copying Ultravisor to protected memory 0x%llx from 0x%llx\n", uv_dt_reg, uv_dt_src); + memcpy((void *)uv_dt_reg, (void *)uv_dt_src, uv_fw_sz); + update_uv_fw_node(uv_dt_reg, uv_fw_sz); + } + + uv_opal->uv_base_addr = uv_dt_reg; + + if (!(sys_fdt_addr = (__be64)create_dtb(dt_root, false))) + prerror("UV: Failed to create system fdt\n"); + + uv_opal->sys_fdt = sys_fdt_addr; + dt_add_property_u64s(uv_fw_node, "sys-fdt", sys_fdt_addr); + +} + +/* + * Preload the UV image from PNOR partition + */ +void uv_preload_image(void) +{ + int ret; + + prlog(PR_DEBUG, "UV: Preload starting\n"); + + if (!alloc_uv()) { + prerror("UV: Memory allocation failed\n"); + return; + } + + ret = start_preload_resource(RESOURCE_ID_UV_IMAGE, RESOURCE_SUBID_NONE, + uv_image, &uv_image_size); + + if (ret != OPAL_SUCCESS) + prerror("UV: platform load failed: %d\n", ret); +} + +/* + * Decompress the UV image + * + * This function modifies the uv_image variable to point to the decompressed + * image location. + */ +void uv_decompress_image(void) +{ + uint64_t uv_fw_addr; + uint32_t uv_fw_size; + + if (uv_image == NULL) { + prerror("UV: Preload hasn't started yet! Aborting.\n"); + return; + } + + if (wait_for_resource_loaded(RESOURCE_ID_UV_IMAGE, + RESOURCE_SUBID_NONE) != OPAL_SUCCESS) { + prerror("UV: Ultravisor image load failed\n"); + return; + } + + uv_xz = local_alloc(this_cpu()->chip_id, sizeof(struct xz_decompress), 8); + if (!uv_xz) { + prerror("UV: Cannot allocate memory for decompression of UV\n"); + return; + } + + /* the load area is the first secure memory range */ + get_uv_fw_region(&uv_fw_addr, &uv_fw_size); + uv_xz->dst = (void *)uv_fw_addr; + uv_xz->dst_size = uv_fw_size; + uv_xz->src = uv_image; + uv_xz->src_size = uv_image_size; + + if (stb_is_container((void*)uv_xz->src, uv_xz->src_size)) + uv_xz->src = uv_xz->src + SECURE_BOOT_HEADERS_SIZE; + + xz_start_decompress(uv_xz); + if ((uv_xz->status != OPAL_PARTIAL) && (uv_xz->status != OPAL_SUCCESS)) + prerror("UV: XZ decompression failed status 0x%x\n", uv_xz->status); +} diff --git a/include/mem_region-malloc.h b/include/mem_region-malloc.h index 4350c564..c1a6b886 100644 --- a/include/mem_region-malloc.h +++ b/include/mem_region-malloc.h @@ -28,4 +28,7 @@ void *__local_alloc(unsigned int chip, size_t size, size_t align, #define local_alloc(chip_id, size, align) \ __local_alloc((chip_id), (size), (align), __location__) +void __local_free(void *ptr, const char *location); +#define local_free(ptr) __local_free(ptr, __location__); + #endif /* __MEM_REGION_MALLOC_H */ diff --git a/include/platform.h b/include/platform.h index 6ecdbe47..04491d6a 100644 --- a/include/platform.h +++ b/include/platform.h @@ -17,6 +17,7 @@ enum resource_id { RESOURCE_ID_INITRAMFS, RESOURCE_ID_CAPP, RESOURCE_ID_IMA_CATALOG, + RESOURCE_ID_UV_IMAGE, RESOURCE_ID_VERSION, RESOURCE_ID_KERNEL_FW, }; diff --git a/include/processor.h b/include/processor.h index a0c2864a..de0ad6bf 100644 --- a/include/processor.h +++ b/include/processor.h @@ -11,6 +11,7 @@ #define MSR_HV PPC_BIT(3) /* Hypervisor mode */ #define MSR_VEC PPC_BIT(38) /* VMX enable */ #define MSR_VSX PPC_BIT(40) /* VSX enable */ +#define MSR_S PPC_BIT(41) /* Secure Mode enable */ #define MSR_EE PPC_BIT(48) /* External Int. Enable */ #define MSR_PR PPC_BIT(49) /* Problem state */ #define MSR_FP PPC_BIT(50) /* Floating Point Enable */ @@ -371,6 +372,17 @@ static inline void st_le32(uint32_t *addr, uint32_t val) asm volatile("stwbrx %0,0,%1" : : "r"(val), "r"(addr), "m"(*addr)); } +/* + * MSR bit check + */ +static inline bool is_msr_bit_set(uint64_t bit) +{ + if (mfmsr() & bit) + return true; + + return false; +} + #endif /* __TEST__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/ultravisor-api.h b/include/ultravisor-api.h new file mode 100644 index 00000000..0301fdd9 --- /dev/null +++ b/include/ultravisor-api.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2018-2019 IBM Corp. */ + +#ifndef __ULTRAVISOR_API_H +#define __ULTRAVISOR_API_H + +#include + +struct uv_opal { + __be32 magic; /**< 'OPUV' 0x4F505556 OPUV_MAGIC */ + __be32 version; /**< uv_opal struct version */ + __be32 uv_api_ver; /**< Current uv api version. */ + __be64 uv_base_addr; /**< Base address of UV in secure memory. */ + __be64 sys_fdt; /**< System FDT. */ + __be64 uv_fdt; /**< UV FDT in secure memory. */ + __be64 uv_mem; /**< struct memcons */ +}; + +#endif /* __ULTRAVISOR_API_H */ diff --git a/include/ultravisor.h b/include/ultravisor.h new file mode 100644 index 00000000..daeb99b6 --- /dev/null +++ b/include/ultravisor.h @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2018-2019 IBM Corp. */ + +#ifndef __ULTRAVISOR_H +#define __ULTRAVISOR_H + +#include +#include +#include + +/* Bit 15 of an address should be set for it to be used as a secure memory area + * for the secure virtual machines */ +#define UV_SECURE_MEM_BIT (PPC_BIT(15)) +#define MAX_COMPRESSED_UV_IMAGE_SIZE 0x40000 /* 256 Kilobytes */ +#define UV_ACCESS_BIT 0x1ULL << 48 +#define UV_LOAD_MAX_SIZE 0x200000 +#define UV_FDT_MAX_SIZE 0x100000 + +extern int start_uv(uint64_t entry, struct uv_opal *uv_opal); +extern bool uv_add_mem_range(__be64 start, __be64 end); +extern void uv_preload_image(void); +extern void uv_decompress_image(void); +extern void init_uv(void); +extern int start_ultravisor(void); +extern long ucall(unsigned long opcode, unsigned long *retbuf, ...); + +#endif /* __ULTRAVISOR_H */ From patchwork Wed Jan 22 15:13:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Grimm X-Patchwork-Id: 1227325 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482ps31WMHz9sR1 for ; Thu, 23 Jan 2020 02:16:23 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 482ps30gc4zDqPf for ; Thu, 23 Jan 2020 02:16:23 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=grimm@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 482prb64cQzDqPR for ; Thu, 23 Jan 2020 02:15:59 +1100 (AEDT) Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00MFDsQk126716 for ; Wed, 22 Jan 2020 10:15:57 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 2xp5yf2q9t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 22 Jan 2020 10:15:56 -0500 Received: from m0098420.ppops.net (m0098420.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00MFEN6Y129492 for ; Wed, 22 Jan 2020 10:15:55 -0500 Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0b-001b2d01.pphosted.com with ESMTP id 2xp5yf2q90-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 10:15:55 -0500 Received: from pps.filterd (ppma01dal.us.ibm.com [127.0.0.1]) by ppma01dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00MFEOZk028891; Wed, 22 Jan 2020 15:15:54 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma01dal.us.ibm.com with ESMTP id 2xksn6ykw2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 15:15:54 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00MFFpGD47907142 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 22 Jan 2020 15:15:51 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AAF2DBE061; Wed, 22 Jan 2020 15:15:51 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A006FBE04F; Wed, 22 Jan 2020 15:15:50 +0000 (GMT) Received: from alain.ibm.com (unknown [9.85.182.18]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 22 Jan 2020 15:15:50 +0000 (GMT) From: Ryan Grimm To: oohall@gmail.com Date: Wed, 22 Jan 2020 10:13:51 -0500 Message-Id: <20200122151354.23683-4-grimm@linux.ibm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200122151354.23683-1-grimm@linux.ibm.com> References: <20200122151354.23683-1-grimm@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-17_05:2020-01-16, 2020-01-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 clxscore=1015 priorityscore=1501 lowpriorityscore=0 phishscore=0 malwarescore=0 mlxscore=0 suspectscore=1 spamscore=0 bulkscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001220136 Subject: [Skiboot] [RFC PATCH v3 3/6] Add memcons support for ultravisor X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: janani@us.ibm.com, suka@us.ibm.com, skiboot@lists.ozlabs.org Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Madhavan Srinivasan The ultravisor console buffer is provided at offset 0x01100000 from the skiboot base. Signed-off-by: Madhavan Srinivasan Signed-off-by: Santosh Sivaraj --- hw/ultravisor.c | 14 ++++++++++++++ include/console.h | 3 +++ include/debug_descriptor.h | 1 + include/mem-map.h | 16 ++++++++++------ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/hw/ultravisor.c b/hw/ultravisor.c index 4222f212..d55d752b 100644 --- a/hw/ultravisor.c +++ b/hw/ultravisor.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -20,6 +22,14 @@ static size_t uv_image_size; struct xz_decompress *uv_xz = NULL; static struct uv_opal *uv_opal; +struct memcons uv_memcons __section(".data.memcons") = { + .magic = MEMCONS_MAGIC, + .obuf_phys = INMEM_UV_CON_START, + .ibuf_phys = INMEM_UV_CON_START + INMEM_UV_CON_OUT_LEN, + .obuf_size = INMEM_UV_CON_OUT_LEN, + .ibuf_size = INMEM_UV_CON_IN_LEN, +}; + const char * wrap_key_prop_str[] = { "wrapping-key-passwd", "wrapping-key-publicname", @@ -321,6 +331,10 @@ void init_uv() } uv_opal->uv_base_addr = uv_dt_reg; + uv_opal->uv_mem = (__be64)&uv_memcons; + + dt_add_property_u64(uv_fw_node, "memcons", (u64)&uv_memcons); + debug_descriptor.uv_memcons_phys = (u64)&uv_memcons; if (!(sys_fdt_addr = (__be64)create_dtb(dt_root, false))) prerror("UV: Failed to create system fdt\n"); diff --git a/include/console.h b/include/console.h index 61448e28..1e7c2a10 100644 --- a/include/console.h +++ b/include/console.h @@ -28,9 +28,12 @@ struct memcons { }; extern struct memcons memcons; +extern struct memcons uv_memcons; #define INMEM_CON_IN_LEN 16 #define INMEM_CON_OUT_LEN (INMEM_CON_LEN - INMEM_CON_IN_LEN) +#define INMEM_UV_CON_IN_LEN 16 +#define INMEM_UV_CON_OUT_LEN (INMEM_UV_CON_LEN - INMEM_UV_CON_IN_LEN) /* Console driver */ struct con_ops { diff --git a/include/debug_descriptor.h b/include/debug_descriptor.h index cbe9293e..949e3d92 100644 --- a/include/debug_descriptor.h +++ b/include/debug_descriptor.h @@ -20,6 +20,7 @@ struct debug_descriptor { /* Memory console */ __be64 memcons_phys; + __be64 uv_memcons_phys; __be32 memcons_tce; __be32 memcons_obuf_tce; __be32 memcons_ibuf_tce; diff --git a/include/mem-map.h b/include/mem-map.h index 8ac11e91..3686b92c 100644 --- a/include/mem-map.h +++ b/include/mem-map.h @@ -91,16 +91,20 @@ #define INMEM_CON_START (SKIBOOT_BASE + 0x01000000) #define INMEM_CON_LEN 0x100000 -/* This is the location of HBRT console buffer at base + 17M */ -#define HBRT_CON_START (SKIBOOT_BASE + 0x01100000) +/* This is the location of our ultravisor console buffer at base + 17M */ +#define INMEM_UV_CON_START (SKIBOOT_BASE + 0x01100000) +#define INMEM_UV_CON_LEN 0x100000 + +/* This is the location of HBRT console buffer at base + 18M */ +#define HBRT_CON_START (SKIBOOT_BASE + 0x01200000) #define HBRT_CON_LEN 0x100000 -/* Tell FSP to put the init data at base + 20M, allocate 8M */ -#define SPIRA_HEAP_BASE (SKIBOOT_BASE + 0x01200000) +/* Tell FSP to put the init data at base + 19M, allocate 8M */ +#define SPIRA_HEAP_BASE (SKIBOOT_BASE + 0x01300000) #define SPIRA_HEAP_SIZE 0x00800000 /* This is our PSI TCE table. It's 256K entries on P8 */ -#define PSI_TCE_TABLE_BASE (SKIBOOT_BASE + 0x01a00000) +#define PSI_TCE_TABLE_BASE (SKIBOOT_BASE + 0x01c00000) #define PSI_TCE_TABLE_SIZE 0x00200000UL /* This is our dump result table after MPIPL. Hostboot will write to this @@ -119,7 +123,7 @@ * * (Ensure this has at least a 64k alignment) */ -#define SKIBOOT_SIZE 0x01c10000 +#define SKIBOOT_SIZE 0x01e00000 /* We start laying out the CPU stacks from here, indexed by PIR * each stack is STACK_SIZE in size (naturally aligned power of From patchwork Wed Jan 22 15:13:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Grimm X-Patchwork-Id: 1227326 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482psL2Wf3z9sR1 for ; Thu, 23 Jan 2020 02:16:38 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 482psK6QhkzDqPC for ; Thu, 23 Jan 2020 02:16:37 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=grimm@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 482ps17391zDqP8 for ; Thu, 23 Jan 2020 02:16:21 +1100 (AEDT) Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00MFDCir078468 for ; Wed, 22 Jan 2020 10:16:19 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xp1jh6exb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 22 Jan 2020 10:16:19 -0500 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00MFDOnU079936 for ; Wed, 22 Jan 2020 10:16:19 -0500 Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xp1jh6ewp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 10:16:19 -0500 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00MFCj33005779; Wed, 22 Jan 2020 15:16:18 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma04dal.us.ibm.com with ESMTP id 2xksn77maa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 15:16:18 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00MFGFIL57475354 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 22 Jan 2020 15:16:15 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 825A4BE04F; Wed, 22 Jan 2020 15:16:15 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 79DA0BE054; Wed, 22 Jan 2020 15:16:14 +0000 (GMT) Received: from alain.ibm.com (unknown [9.85.182.18]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 22 Jan 2020 15:16:14 +0000 (GMT) From: Ryan Grimm To: oohall@gmail.com Date: Wed, 22 Jan 2020 10:13:52 -0500 Message-Id: <20200122151354.23683-5-grimm@linux.ibm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200122151354.23683-1-grimm@linux.ibm.com> References: <20200122151354.23683-1-grimm@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-17_05:2020-01-16, 2020-01-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 bulkscore=0 suspectscore=1 lowpriorityscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 mlxscore=0 impostorscore=0 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001220136 Subject: [Skiboot] [RFC PATCH v3 4/6] xscoms: read/write xscoms using ucall X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: janani@us.ibm.com, suka@us.ibm.com, skiboot@lists.ozlabs.org Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Madhavan Srinivasan xscom registers are in the secure memory area when secure mode is enabled. These registers cannot be accessed directly and need to use ultravisor services using ultracall. Signed-off-by: Madhavan Srinivasan Signed-off-by: Santosh Sivaraj [ linuxram: Set uv_present just after starting UV ] Signed-off-by: Ram Pai [ grimm: Don't check MSR in xscom read/write ] Signed-off-by: Ryan Grimm --- hw/ultravisor.c | 4 ++++ include/ultravisor.h | 22 ++++++++++++++++++++++ include/xscom.h | 11 +++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/hw/ultravisor.c b/hw/ultravisor.c index d55d752b..a5553757 100644 --- a/hw/ultravisor.c +++ b/hw/ultravisor.c @@ -17,6 +17,7 @@ #include #include +bool uv_present = false; static char *uv_image = NULL; static size_t uv_image_size; struct xz_decompress *uv_xz = NULL; @@ -251,6 +252,9 @@ int start_ultravisor(void) cpu_start_ultravisor((void *)uv_opal); + /* From now on XSCOM must go through ucall */ + uv_present = true; + while (i > 0) cpu_wait_job(jobs[--i], true); diff --git a/include/ultravisor.h b/include/ultravisor.h index daeb99b6..d212f463 100644 --- a/include/ultravisor.h +++ b/include/ultravisor.h @@ -12,10 +12,15 @@ * for the secure virtual machines */ #define UV_SECURE_MEM_BIT (PPC_BIT(15)) #define MAX_COMPRESSED_UV_IMAGE_SIZE 0x40000 /* 256 Kilobytes */ +#define UV_READ_SCOM 0xF114 +#define UV_WRITE_SCOM 0xF118 +#define UCALL_BUFSIZE 4 #define UV_ACCESS_BIT 0x1ULL << 48 #define UV_LOAD_MAX_SIZE 0x200000 #define UV_FDT_MAX_SIZE 0x100000 +extern bool uv_present; + extern int start_uv(uint64_t entry, struct uv_opal *uv_opal); extern bool uv_add_mem_range(__be64 start, __be64 end); extern void uv_preload_image(void); @@ -24,4 +29,21 @@ extern void init_uv(void); extern int start_ultravisor(void); extern long ucall(unsigned long opcode, unsigned long *retbuf, ...); +static inline int uv_xscom_read(u64 partid, u64 pcb_addr, u64 *val) +{ + long rc; + unsigned long retbuf[UCALL_BUFSIZE]; + + rc = ucall(UV_READ_SCOM, retbuf, partid, pcb_addr); + *val = retbuf[0]; + return rc; +} + +static inline int uv_xscom_write(u64 partid, u64 pcb_addr, u64 val) +{ + unsigned long retbuf[UCALL_BUFSIZE]; + + return ucall(UV_WRITE_SCOM, retbuf, partid, pcb_addr, val); +} + #endif /* __ULTRAVISOR_H */ diff --git a/include/xscom.h b/include/xscom.h index 8a466d56..2f4c819b 100644 --- a/include/xscom.h +++ b/include/xscom.h @@ -7,6 +7,7 @@ #include #include #include +#include /* * SCOM "partID" definitions: @@ -174,10 +175,16 @@ extern void _xscom_unlock(void); /* Targeted SCOM access */ static inline int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val) { - return _xscom_read(partid, pcb_addr, val, true); + if (!uv_present) + return _xscom_read(partid, pcb_addr, val, true); + + return uv_xscom_read(partid, pcb_addr, val); } static inline int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) { - return _xscom_write(partid, pcb_addr, val, true); + if (!uv_present) + return _xscom_write(partid, pcb_addr, val, true); + + return uv_xscom_write(partid, pcb_addr, val); } extern int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask); From patchwork Wed Jan 22 15:13:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Grimm X-Patchwork-Id: 1227327 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482psm0Lj8z9sR1 for ; Thu, 23 Jan 2020 02:17:00 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 482psl6ZxvzDqPC for ; Thu, 23 Jan 2020 02:16:59 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=grimm@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 482psd6bVwzDqP8 for ; Thu, 23 Jan 2020 02:16:53 +1100 (AEDT) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00MFDLrX132730 for ; Wed, 22 Jan 2020 10:16:50 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xp93pn5fk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 22 Jan 2020 10:16:50 -0500 Received: from m0098421.ppops.net (m0098421.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00MFDfIH134543 for ; Wed, 22 Jan 2020 10:16:50 -0500 Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xp93pn5ex-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 10:16:50 -0500 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00MF9pd3002252; Wed, 22 Jan 2020 15:16:49 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma04dal.us.ibm.com with ESMTP id 2xksn77mfh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 15:16:49 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00MFGkSc51184010 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 22 Jan 2020 15:16:46 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C7EE4BE051; Wed, 22 Jan 2020 15:16:46 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B3FA2BE058; Wed, 22 Jan 2020 15:16:45 +0000 (GMT) Received: from alain.ibm.com (unknown [9.85.182.18]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 22 Jan 2020 15:16:45 +0000 (GMT) From: Ryan Grimm To: oohall@gmail.com Date: Wed, 22 Jan 2020 10:13:53 -0500 Message-Id: <20200122151354.23683-6-grimm@linux.ibm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200122151354.23683-1-grimm@linux.ibm.com> References: <20200122151354.23683-1-grimm@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-17_05:2020-01-16, 2020-01-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 lowpriorityscore=0 malwarescore=0 mlxlogscore=999 suspectscore=1 impostorscore=0 priorityscore=1501 phishscore=0 adultscore=0 clxscore=1015 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001220136 Subject: [Skiboot] [RFC PATCH v3 5/6] skiboot/imc: Disable IMC node when UV enabled X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: janani@us.ibm.com, suka@us.ibm.com, skiboot@lists.ozlabs.org Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Madhavan Srinivasan Remove the IMC nodes when the ultravisor is enabled, since both HOMER and IMC scoms are not accessable in hypervisor state. Signed-off-by: Madhavan Srinivasan --- hw/imc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/imc.c b/hw/imc.c index 3a5382c0..576eac87 100644 --- a/hw/imc.c +++ b/hw/imc.c @@ -603,6 +603,17 @@ imc_mambo: if (pause_microcode_at_boot()) goto err; + /* + * If MSR(S) bit is set, disable IMC nodes. + * IMC nodes need access to specific scom and HOMER region + * which are not accessible from hypervisor. + * + * At this point uv_present cant be used since uv_init() + * is called much later. Hencing checking for the MSR bit here. + */ + if (is_msr_bit_set(MSR_S)) + goto err; + /* * If the dt_attach_root() fails, "imc-counters" node will not be * seen in the device-tree and hence OS should not make any From patchwork Wed Jan 22 15:13:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Grimm X-Patchwork-Id: 1227328 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482ptB6ZCcz9sR1 for ; Thu, 23 Jan 2020 02:17:22 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 482ptB5kYfzDqPC for ; Thu, 23 Jan 2020 02:17:22 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=grimm@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 482pt61zSHzDqNH for ; Thu, 23 Jan 2020 02:17:18 +1100 (AEDT) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00MFDJ2L132616 for ; Wed, 22 Jan 2020 10:17:16 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xp93pn61w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 22 Jan 2020 10:17:16 -0500 Received: from m0098421.ppops.net (m0098421.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00MFDt3L135265 for ; Wed, 22 Jan 2020 10:17:15 -0500 Received: from ppma02dal.us.ibm.com (a.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.10]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xp93pn5xs-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 10:17:15 -0500 Received: from pps.filterd (ppma02dal.us.ibm.com [127.0.0.1]) by ppma02dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00MFF7PY013012; Wed, 22 Jan 2020 15:17:09 GMT Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by ppma02dal.us.ibm.com with ESMTP id 2xksn77n88-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 22 Jan 2020 15:17:09 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00MFH6Yh31850760 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 22 Jan 2020 15:17:06 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 66758BE058; Wed, 22 Jan 2020 15:17:06 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5332CBE054; Wed, 22 Jan 2020 15:17:05 +0000 (GMT) Received: from alain.ibm.com (unknown [9.85.182.18]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 22 Jan 2020 15:17:05 +0000 (GMT) From: Ryan Grimm To: oohall@gmail.com Date: Wed, 22 Jan 2020 10:13:54 -0500 Message-Id: <20200122151354.23683-7-grimm@linux.ibm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200122151354.23683-1-grimm@linux.ibm.com> References: <20200122151354.23683-1-grimm@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-17_05:2020-01-16, 2020-01-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 lowpriorityscore=0 malwarescore=0 mlxlogscore=999 suspectscore=1 impostorscore=0 priorityscore=1501 phishscore=0 adultscore=0 clxscore=1015 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001220136 Subject: [Skiboot] [RFC PATCH v3 6/6] libstb/trustedboot: Map UV image measurement to PCR4 X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: janani@us.ibm.com, suka@us.ibm.com, skiboot@lists.ozlabs.org Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Claudio Carvalho This maps the ultravisor image to be measured to PCR4. The image is automatically verified and measured hen it is loaded from PNOR. Signed-off-by: Claudio Carvalho --- libstb/trustedboot.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libstb/trustedboot.c b/libstb/trustedboot.c index 3f977de1..87f3b6bf 100644 --- a/libstb/trustedboot.c +++ b/libstb/trustedboot.c @@ -45,6 +45,7 @@ static struct { { RESOURCE_ID_KERNEL, PCR_4}, { RESOURCE_ID_CAPP, PCR_4}, { RESOURCE_ID_VERSION, PCR_4}, /* Also data for Hostboot */ + { RESOURCE_ID_UV_IMAGE, PCR_4}, }; /*