From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) by mx.groups.io with SMTP id smtpd.web11.33402.1679919603840649131 for ; Mon, 27 Mar 2023 05:20:03 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@ventanamicro.com header.s=google header.b=BKl344lT; spf=pass (domain: ventanamicro.com, ip: 209.85.214.181, mailfrom: sunilvl@ventanamicro.com) Received: by mail-pl1-f181.google.com with SMTP id c18so8218288ple.11 for ; Mon, 27 Mar 2023 05:20:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1679919603; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=i/omcpOXDI7HD0Gi3Ax4iw6kiHQ9CLNZFZs1KjZWqqE=; b=BKl344lTOfgKTvu4sq2yfalYgDadE5J2TULDDzzfKU/Ik/wnUFnnHaRHOF6/mPXVoq ngsm0DZ25mySAPn88f2PtEEhFPITDs8LzJp6pE7AcIYksDWuaxocp+v96tLqjXwpV6WJ IcOJO2wbHTdVFKkBCJ07Wr9own3zcNmdNTBjN2gA0hHCuhoVoPgmKCB5jsj+uxmxBN2y w0vSbN3V7NGA/OJUnZo6Wj+v2dgIQ+vftb9XvUXQP9pVaErEPWz7fZ2WJprrkfze0M93 eAJQ2h7Je3ryxKM0hBO8i9uhYuaVzzbcw/cHTBYYhUgujltdX9Axrje2qMYsKkW2gKeB zfPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679919603; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=i/omcpOXDI7HD0Gi3Ax4iw6kiHQ9CLNZFZs1KjZWqqE=; b=ZPfGVKAY6PiTijGIX8GGVqkEyvUDIEWpTqGAF0bR7+czp8mO3e7k55gbyrQnSEFc6W 2k24eQE4ZM4H/IhgjedAr35aV/UQRknMzVMFORmCeanN8nCq7lvGTpf430AougOibaM1 iI22x1jD8oFuRmn8muEFPacB2/qgl2JXT8t9ShK1LsnwGjtkuE9W55BKVv8/xG2CIhX6 StVfm63/ciU5KGCKW4nOkEvMvlFNqQVyK23WSabp+sNljbBmrxlbLD4IZnp4kCzRfOJY 3vJv/bNx8vAAYZfjvTBbqns00A+G5PL3hab0urzY7YOMF7XREr0lqRaS7kzolj7dm7fO lVOA== X-Gm-Message-State: AAQBX9f2Pz61ICO0Px2bbbBno8xjgCyG3M5Xs7+If2un8FxwvW6NHWRB M6nwMI22OBomd8qt569lTcTD/KNytiH8dtBxAIo= X-Google-Smtp-Source: AKy350YLMvFyUYhBMeGRLfbwLA/DAZtCde7ng773HSFlOAkfUqLtLD9V1+7f60yCwK8DqB+NGO9reQ== X-Received: by 2002:a17:90b:1bc2:b0:23d:39e0:142 with SMTP id oa2-20020a17090b1bc200b0023d39e00142mr12586506pjb.42.1679919602933; Mon, 27 Mar 2023 05:20:02 -0700 (PDT) Return-Path: Received: from kerodi.Dlink ([106.51.187.127]) by smtp.gmail.com with ESMTPSA id p11-20020a17090a4f0b00b0023cff7e39a6sm4259451pjh.22.2023.03.27.05.20.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Mar 2023 05:20:02 -0700 (PDT) From: "Sunil V L" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Andrei Warkentin Subject: [PATCH v2 1/1] OvmfPkg/RiscVVirt: Support multiple reserved memory ranges Date: Mon, 27 Mar 2023 17:49:58 +0530 Message-Id: <20230327121958.1806982-1-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit M-mode firmware ranges should not be used by EDK2/OS. Currently, we search for mmode_resv0 node in FDT and mark it as the reserved memory in EFI memory map. However, if there are multiple M-mode firmware ranges, then this will miss those extra ranges allowing the OS to access the memory and hit a fault. This issue is exposed since recent opensbi started creating two ranges for text and data. Fix this by searching for all reserved memory nodes and marking them as reserved in the EFI memory map. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Andrei Warkentin Signed-off-by: Sunil V L Reviewed-by: Andrei Warkentin --- Changes since v1: 1) Updated IN/OUT and function comment as per Andrei's feedback. 2) Added RB tag OvmfPkg/RiscVVirt/Sec/Memory.c | 226 ++++++++++++++++++++++----------- 1 file changed, 149 insertions(+), 77 deletions(-) diff --git a/OvmfPkg/RiscVVirt/Sec/Memory.c b/OvmfPkg/RiscVVirt/Sec/Memory.c index 70935b07b56b..f7a72c7bb4fb 100644 --- a/OvmfPkg/RiscVVirt/Sec/Memory.c +++ b/OvmfPkg/RiscVVirt/Sec/Memory.c @@ -38,31 +38,6 @@ BuildMemoryTypeInformationHob ( VOID ); -/** - Build reserved memory range resource HOB. - - @param MemoryBase Reserved memory range base address. - @param MemorySize Reserved memory range size. - -**/ -STATIC -VOID -AddReservedMemoryBaseSizeHob ( - EFI_PHYSICAL_ADDRESS MemoryBase, - UINT64 MemorySize - ) -{ - BuildResourceDescriptorHob ( - EFI_RESOURCE_MEMORY_RESERVED, - EFI_RESOURCE_ATTRIBUTE_PRESENT | - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | - EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | - EFI_RESOURCE_ATTRIBUTE_TESTED, - MemoryBase, - MemorySize - ); -} - /** Create memory range resource HOB using the memory base address and size. @@ -74,8 +49,8 @@ AddReservedMemoryBaseSizeHob ( STATIC VOID AddMemoryBaseSizeHob ( - EFI_PHYSICAL_ADDRESS MemoryBase, - UINT64 MemorySize + IN EFI_PHYSICAL_ADDRESS MemoryBase, + IN UINT64 MemorySize ) { BuildResourceDescriptorHob ( @@ -103,8 +78,8 @@ AddMemoryBaseSizeHob ( STATIC VOID AddMemoryRangeHob ( - EFI_PHYSICAL_ADDRESS MemoryBase, - EFI_PHYSICAL_ADDRESS MemoryLimit + IN EFI_PHYSICAL_ADDRESS MemoryBase, + IN EFI_PHYSICAL_ADDRESS MemoryLimit ) { AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); @@ -132,39 +107,152 @@ InitMmu ( STATIC VOID InitializeRamRegions ( - EFI_PHYSICAL_ADDRESS SystemMemoryBase, - UINT64 SystemMemorySize, - EFI_PHYSICAL_ADDRESS MmodeResvBase, - UINT64 MmodeResvSize + IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, + IN UINT64 SystemMemorySize ) { - /* - * M-mode FW can be loaded anywhere in memory but should not overlap - * with the EDK2. This can happen if some other boot code loads the - * M-mode firmware. - * - * The M-mode firmware memory should be marked as reserved memory - * so that OS doesn't use it. - */ - DEBUG (( - DEBUG_INFO, - "%a: M-mode FW Memory Start:0x%lx End:0x%lx\n", - __FUNCTION__, - MmodeResvBase, - MmodeResvBase + MmodeResvSize - )); - AddReservedMemoryBaseSizeHob (MmodeResvBase, MmodeResvSize); - - if (MmodeResvBase > SystemMemoryBase) { - AddMemoryRangeHob (SystemMemoryBase, MmodeResvBase); - } - AddMemoryRangeHob ( - MmodeResvBase + MmodeResvSize, + SystemMemoryBase, SystemMemoryBase + SystemMemorySize ); } +/** Get the number of cells for a given property + + @param[in] Fdt Pointer to Device Tree (DTB) + @param[in] Node Node + @param[in] Name Name of the property + + @return Number of cells. +**/ +STATIC +INT32 +GetNumCells ( + IN VOID *Fdt, + IN INT32 Node, + IN CONST CHAR8 *Name + ) +{ + CONST INT32 *Prop; + INT32 Len; + UINT32 Val; + + Prop = fdt_getprop (Fdt, Node, Name, &Len); + if (Prop == NULL) { + return Len; + } + + if (Len != sizeof (*Prop)) { + return -FDT_ERR_BADNCELLS; + } + + Val = fdt32_to_cpu (*Prop); + if (Val > FDT_MAX_NCELLS) { + return -FDT_ERR_BADNCELLS; + } + + return (INT32)Val; +} + +/** Mark reserved memory ranges in the EFI memory map + + The M-mode firmware ranges should not be used by the + EDK2/OS. These ranges are passed via device tree using reserved + memory nodes. Parse the DT and mark those ranges as of + type EfiReservedMemoryType. + + NOTE: Device Tree spec section 3.5.4 says reserved memory regions + without no-map property should be installed as EfiBootServicesData. + As per UEFI spec, memory of type EfiBootServicesData can be used + by the OS after ExitBootServices(). + This is not an issue for DT since OS can parse the DT also along + with EFI memory map and avoid using these ranges. But with ACPI, + there is no such mechanisms possible. + Since EDK2 needs to support both DT and ACPI, we are deviating + from the DT spec and marking all reserved memory ranges as + EfiReservedMemoryType itself irrespective of no-map. + + @param FdtPointer Pointer to FDT + +**/ +STATIC +VOID +AddReservedMemoryMap ( + IN VOID *FdtPointer + ) +{ + CONST INT32 *RegProp; + INT32 Node; + INT32 SubNode; + INT32 Len; + EFI_PHYSICAL_ADDRESS Addr; + UINT64 Size; + INTN NumRsv, i; + INT32 NumAddrCells, NumSizeCells; + + NumRsv = fdt_num_mem_rsv (FdtPointer); + + /* Look for an existing entry and add it to the efi mem map. */ + for (i = 0; i < NumRsv; i++) { + if (fdt_get_mem_rsv (FdtPointer, i, &Addr, &Size) != 0) { + continue; + } + + BuildMemoryAllocationHob ( + Addr, + Size, + EfiReservedMemoryType + ); + } + + /* process reserved-memory */ + Node = fdt_subnode_offset (FdtPointer, 0, "reserved-memory"); + if (Node >= 0) { + NumAddrCells = GetNumCells (FdtPointer, Node, "#address-cells"); + if (NumAddrCells <= 0) { + return; + } + + NumSizeCells = GetNumCells (FdtPointer, Node, "#size-cells"); + if (NumSizeCells <= 0) { + return; + } + + fdt_for_each_subnode (SubNode, FdtPointer, Node) { + RegProp = fdt_getprop (FdtPointer, SubNode, "reg", &Len); + + if ((RegProp != 0) && (Len == ((NumAddrCells + NumSizeCells) * sizeof (INT32)))) { + Addr = fdt32_to_cpu (RegProp[0]); + + if (NumAddrCells > 1) { + Addr = (Addr << 32) | fdt32_to_cpu (RegProp[1]); + } + + RegProp += NumAddrCells; + Size = fdt32_to_cpu (RegProp[0]); + + if (NumSizeCells > 1) { + Size = (Size << 32) | fdt32_to_cpu (RegProp[1]); + } + + DEBUG (( + DEBUG_INFO, + "%a: Adding Reserved Memory Addr = 0x%llx, Size = 0x%llx\n", + __func__, + Addr, + Size + )); + + BuildMemoryAllocationHob ( + Addr, + Size, + EfiReservedMemoryType + ); + } + } + } +} + /** Initialize memory hob based on the DTB information. @@ -183,8 +271,6 @@ MemoryPeimInitialization ( INT32 Node, Prev; INT32 Len; VOID *FdtPointer; - EFI_PHYSICAL_ADDRESS MmodeResvBase; - UINT64 MmodeResvSize; FirmwareContext = NULL; GetFirmwareContextPointer (&FirmwareContext); @@ -200,16 +286,6 @@ MemoryPeimInitialization ( return EFI_UNSUPPORTED; } - /* try to locate the reserved memory opensbi node */ - Node = fdt_path_offset (FdtPointer, "/reserved-memory/mmode_resv0"); - if (Node >= 0) { - RegProp = fdt_getprop (FdtPointer, Node, "reg", &Len); - if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) { - MmodeResvBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); - MmodeResvSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1)); - } - } - // Look for the lowest memory node for (Prev = 0; ; Prev = Node) { Node = fdt_next_node (FdtPointer, Prev, NULL); @@ -235,16 +311,10 @@ MemoryPeimInitialization ( CurBase + CurSize - 1 )); - if ((MmodeResvBase >= CurBase) && ((MmodeResvBase + MmodeResvSize) <= (CurBase + CurSize))) { - InitializeRamRegions ( - CurBase, - CurSize, - MmodeResvBase, - MmodeResvSize - ); - } else { - AddMemoryBaseSizeHob (CurBase, CurSize); - } + InitializeRamRegions ( + CurBase, + CurSize + ); } else { DEBUG (( DEBUG_ERROR, @@ -255,6 +325,8 @@ MemoryPeimInitialization ( } } + AddReservedMemoryMap (FdtPointer); + InitMmu (); BuildMemoryTypeInformationHob (); -- 2.34.1