From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by mx.groups.io with SMTP id smtpd.web10.12692.1675894133510615407 for ; Wed, 08 Feb 2023 14:08:54 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FCPRHLhP; spf=pass (domain: kernel.org, ip: 145.40.68.75, mailfrom: ardb@kernel.org) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 650F3B81FCA for ; Wed, 8 Feb 2023 22:08:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E061C433A7 for ; Wed, 8 Feb 2023 22:08:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1675894129; bh=uv1LSS4/iG6JWS2V6a005ZQIvxbN+t6nR4WndiAjIDI=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=FCPRHLhP3oS+H68J+8QnxuLycNsE90JjRL8qt/0HqZKhQGc43DDPwhiOmI1piBAtz M3tjvsWSj8Jl9SI5z+dYiYqZMMXDwDYvjmNn+WmmEsqZNZlsatSJoDmGyokFJhbjVO jx4NOWaxPIucFBPimciPzLDNBROKAYn2jRdHArVrhofRdWI6v25JODaHD49bmdeifJ dCBspCDdZOoq73K6o77POzrKqnhBwxkAcfKaqi7WbphM19Ld4EapYWpOnBHXpNHHXE SxCm2MIRHt8N2saRSc+C99c3IajN5trkTKw5ILtmnkAgTCsJDwzyaQ0e7YdT1Q7mHe iOX2NPvjSlUyg== Received: by mail-lj1-f178.google.com with SMTP id b13so21007019ljf.8 for ; Wed, 08 Feb 2023 14:08:49 -0800 (PST) X-Gm-Message-State: AO0yUKXDa5tOqukkmhYCcQH//5d+lDJVut7r2hMh9PvpWZmUN30870U5 r/tnv3qJ4e2lhLdqM5X2beeATbSVCddZPoHqSmk= X-Google-Smtp-Source: AK7set+EuVT5axmKEKSGohKXbUP8Tdk761upqCTA7vNY2vf0XBl9m9LErKHDcmcXWOOy+srRIz7dOTWjcrrcOfFQx84= X-Received: by 2002:a2e:95d4:0:b0:293:2b74:efd3 with SMTP id y20-20020a2e95d4000000b002932b74efd3mr490725ljh.178.1675894127410; Wed, 08 Feb 2023 14:08:47 -0800 (PST) MIME-Version: 1.0 References: <20230208175812.700129-1-ardb@kernel.org> <20230208175812.700129-4-ardb@kernel.org> <32ae5b04-0a0c-c8c4-7b2d-cee3ac2a2517@taylorbeebe.com> In-Reply-To: <32ae5b04-0a0c-c8c4-7b2d-cee3ac2a2517@taylorbeebe.com> From: "Ard Biesheuvel" Date: Wed, 8 Feb 2023 23:08:35 +0100 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH 3/3] MdeModulePkg/DxeCore: Unconditionally set memory protections To: Taylor Beebe Cc: devel@edk2.groups.io, Michael Kinney , Liming Gao , Jiewen Yao , Michael Kubacki , Sean Brogan , Rebecca Cran , Leif Lindholm , Sami Mujawar , =?UTF-8?Q?Marvin_H=C3=A4user?= Content-Type: text/plain; charset="UTF-8" On Wed, 8 Feb 2023 at 20:12, Taylor Beebe wrote: > > I ran some tests and did some quick napkin math. Based on the time it > takes to perform the SetMemoryAttributes() routine on QEMU, as long as > <79% of the calls to ApplyMemoryProtectionPolicy() actually require a > subsequent call to SetMemoryAttributes(), it is more efficient to walk > the page/translation table to check if the attributes actually need to > be updated. Even on a platform with varied NX policy settings, the > number of times the attributes need to be updated is less than 0.0005% > of all calls to ApplyMemoryProtectionPolicy() (likely due to most > allocations being BootServicesData). > > Once the ARM and X64 implementations of the Memory Attribute Protocol > are in, would you be open to updating this block to utilize the protocol > to check the attributes of the region being updated? > Yes, that was what I had in my initial prototype. However, I'm not sure how walking the page tables to retrieve all existing attributes is fundamentally different from walking the page tables to set them, given that everything is cached and we are running uniprocessor at this point. > On 2/8/2023 10:25 AM, Ard Biesheuvel wrote: > > On Wed, 8 Feb 2023 at 18:58, Ard Biesheuvel wrote: > >> > >> Instead of relying on a questionable heuristic that avoids calling into > >> the SetMemoryAttributes () DXE service when the old memory type and the > >> new one are subjected to the same NX memory protection policy, make this > >> call unconditionally. This avoids corner cases where memory region > >> attributes are out of sync with the policy, either due to the fact that > >> we are in the middle of ramping up the protections, or due to explicit > >> invocations of SetMemoryAttributes() by drivers. > >> > >> This requires the architecture page table code to be able to deal with > >> this, in particular, it needs to be robust against potential recursion > >> due to NX policies being applied to newly allocated page tables. > >> > >> Signed-off-by: Ard Biesheuvel > >> --- > >> MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 29 -------------------- > >> 1 file changed, 29 deletions(-) > >> > >> diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c > >> index 36987843f142..503feb72b5d0 100644 > >> --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c > >> +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c > >> @@ -1263,9 +1263,7 @@ ApplyMemoryProtectionPolicy ( > >> IN UINT64 Length > >> ) > >> { > >> - UINT64 OldAttributes; > >> UINT64 NewAttributes; > >> - EFI_STATUS Status; > >> > >> // > >> // The policy configured in PcdDxeNxMemoryProtectionPolicy > >> @@ -1320,32 +1318,5 @@ ApplyMemoryProtectionPolicy ( > >> // > >> NewAttributes = GetPermissionAttributeForMemoryType (NewType); > >> > >> - if (OldType != EfiMaxMemoryType) { > >> - OldAttributes = GetPermissionAttributeForMemoryType (OldType); > >> - if (!mAfterDxeNxMemoryProtectionInit && > >> - (OldAttributes == NewAttributes)) { > >> - return EFI_SUCCESS; > >> - } > >> - > > > > This removes some code that does not actually exist - apologies. > > > > It comes down to just removing the conditional checks here, though, > > and perform the tail call below unconditionally. > > > >> - // > >> - // If available, use the EFI memory attribute protocol to obtain > >> - // the current attributes of the region. If the entire region is > >> - // covered and the attributes match, we don't have to do anything. > >> - // > >> - if (mMemoryAttribute != NULL) { > >> - Status = mMemoryAttribute->GetMemoryAttributes (mMemoryAttribute, > >> - Memory, > >> - Length, > >> - &OldAttributes > >> - ); > >> - if (!EFI_ERROR (Status) && (OldAttributes == NewAttributes)) { > >> - return EFI_SUCCESS; > >> - } > >> - } > >> - } else if (NewAttributes == 0) { > >> - // newly added region of a type that does not require protection > >> - return EFI_SUCCESS; > >> - } > >> - > >> return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes); > >> } > >> -- > >> 2.39.1 > >>