From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.groups.io with SMTP id smtpd.web11.38008.1615217879511181773 for ; Mon, 08 Mar 2021 07:37:59 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=FHMYCR6p; spf=pass (domain: redhat.com, ip: 216.205.24.124, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615217878; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JIO/ZIShsmjdu+K5WMR+IMXN9IeGXIXZQZ8qOC4OJaw=; b=FHMYCR6pDwclrUQ4+/ojMdnxER/yky3tIqoZ48KLqhivv6RocMyliJwItAxT91OkIdYCNj tLKxUubZfU+HqUVmfSdDwjlmolkFbYEA051ul4RH/T6gFO5u2LVqVI2BF4WRmJlN3jWzVZ YXesALflU1oYaRmeNJgUjsBQTkYQJjk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-289-QvE40pbwNdOYglIDPgGh_w-1; Mon, 08 Mar 2021 10:37:54 -0500 X-MC-Unique: QvE40pbwNdOYglIDPgGh_w-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id EACE226862; Mon, 8 Mar 2021 15:37:52 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-112-175.ams2.redhat.com [10.36.112.175]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91F4C1001B2C; Mon, 8 Mar 2021 15:37:51 +0000 (UTC) Subject: Re: [edk2-devel] [RFC][patch] Add a new library class RegisterFilterLib in edk2 to filter/trace port IO/MMIO/MSR access To: devel@edk2.groups.io, dandan.bi@intel.com Cc: Michael D Kinney , Liming Gao , Zhiguang Liu References: <20210308051532.13872-1-dandan.bi@intel.com> From: "Laszlo Ersek" Message-ID: Date: Mon, 8 Mar 2021 16:37:50 +0100 MIME-Version: 1.0 In-Reply-To: <20210308051532.13872-1-dandan.bi@intel.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lersek@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 03/08/21 06:15, Dandan Bi wrote: > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3246 > > 1.Purpose: > Skip port IO/MMIO/MSR access in some emulatoion env. > Trace port IO/MMIO/MSR access. > > 2.Plan to do in Edk2: > Filter and trace in low level APIs in BaseIoLibIntrinsic and BaseLib. > Add a new library class (RegisterFilterLib) for the filter and trace functionality. > > 3.Plan to filter and trace scope in Edk2 : > a. Port IO R/W: IA32 X64 (Only filter/trace for IA32 X64) > b. MMIO R/W: IA32 X64 EBC ARM AARCH64 RISCV64 (Filter/trace for the Arches supported in BaseIoLibIntrinsic.inf) > c. MSR R/W: IA32 X64 (Only filter/trace for IA32 X64, if other ARCH has similar use case can add new APIs per needs) > > 4.RegisterFilterLib Library Class: > a. Add RegisterFilterLib library class for the filter and trace operation. > b. Add RegisterFilterLib.h in MdePkg/Include/Library. > c. 12 APIs will be added to filter and trace port IO, MMIO and MSR access. > d. Add a NULL instance RegisterFilterLibNull in MdePkg/Library.(Verified that null instance will not impact binary size.) > e. Platform can implement its own RegisterFilterLib instance. > > 12 APIs can be divided into 2 categories: > 6 [Before] APIs use to check whether need to execute port IO/MMIO/MSR access or do some tracing before access. > 6 [After] APIs use to trace after port IO/MMIO/MSR access. > The detailed API definitions are included in this patch. > > For port IO access: > FilterBeforeIoRead > FilterAfterIoRead > FilterBeforeIoWrite > FilterAfterIoWrite > > For MMIO access: > FilterBeforeMmIoRead > FilterAfterMmIoRead > FilterBeforeMmIoWrite > FilterAfterMmIoWrite > > For MSR access: > FilterBeforeMsrRead > FilterAfterMsrRead > FilterBeforeMsrWrite > FilterAfterMsrWrite > > 5.Change and Impact > a. Add the RegisterFilterLib libary class and RegisterFilterLibNull instance firstly. > b. Update the dsc in edk2 and edk2-platform repo to consume the RegisterFilterLibNull instance. > c. Update the BaseLib and IoLib to consume RegisterFilterLib. > > This is an incompatible change. > No code change in BaseLib and IoLib consumers, only need to change dsc to consume new FilterLib instance. > Update BaseIoLibIntrinsic.inf and BaseIoLibIntrinsicSev.inf to consume RegisterFilterLib for all supported Arch > Update BaseLib.inf to consume RegisterFilterLib only for IA32 and X64 Seems like a sound plan, but there are more IoLib instances than the above: MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.inf MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.inf Thanks Laszlo > > This topic has been reviewed in Tiano Design meeting of 2021/0305 > RegisterFilterLib header file and desgin foil can be found in: > https://edk2.groups.io/g/devel/files/Designs/2021/0305 > > > Cc: Michael D Kinney > Cc: Liming Gao > Cc: Zhiguang Liu > Signed-off-by: Dandan Bi > --- > MdePkg/Include/Library/RegisterFilterLib.h | 224 +++++++++++++++++++++ > 1 file changed, 224 insertions(+) > create mode 100644 MdePkg/Include/Library/RegisterFilterLib.h > > diff --git a/MdePkg/Include/Library/RegisterFilterLib.h b/MdePkg/Include/Library/RegisterFilterLib.h > new file mode 100644 > index 0000000000..be111304ba > --- /dev/null > +++ b/MdePkg/Include/Library/RegisterFilterLib.h > @@ -0,0 +1,224 @@ > +/** @file > + Public include file for the Port IO/MMIO/MSR filter Library > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef __REGISTER_FILTER_LIB_H__ > +#define __REGISTER_FILTER_LIB_H__ > + > +typedef enum { > + FilterWidth8, > + FilterWidth16, > + FilterWidth32, > + FilterWidth64 > +} FILTER_IO_WIDTH; > + > +/** > + Filter IO read operation before read IO port. > + It is used to filter IO read operation. > + > + It will return the flag to decide whether require read real IO port. > + It can be used for emulation environment. > + > + @param[in] Width Signifies the width of the I/O operation. > + @param[in] Address The base address of the I/O operation. > + @param[in] Buffer The destination buffer to store the results. > + > +**/ > +BOOLEAN > +EFIAPI > +FilterBeforeIoRead ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN OUT VOID *Buffer > + ); > + > +/** > + Trace IO read operation after read IO port. > + It is used to trace IO operation. > + > + @param[in] Width Signifies the width of the I/O operation. > + @param[in] Address The base address of the I/O operation. > + @param[in] Buffer The destination buffer to store the results. > + > +**/ > +VOID > +EFIAPI > +FilterAfterIoRead ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN VOID *Buffer > + ); > +/** > + Filter IO Write operation before wirte IO port. > + It is used to filter IO operation. > + > + It will return the flag to decide whether require read write IO port. > + It can be used for emulation environment. > + > + @param[in] Width Signifies the width of the I/O operation. > + @param[in] Address The base address of the I/O operation. > + @param[in] Buffer The source buffer from which to BeforeWrite data. > + > +**/ > +BOOLEAN > +EFIAPI > +FilterBeforeIoWrite ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN VOID *Buffer > + ); > + > + /** > + Trace IO Write operation after wirte IO port. > + It is used to trace IO operation. > + > + @param[in] Width Signifies the width of the I/O operation. > + @param[in] Address The base address of the I/O operation. > + @param[in] Buffer The source buffer from which to BeforeWrite data. > + > +**/ > +VOID > +EFIAPI > +FilterAfterIoWrite ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN VOID *Buffer > + ); > + > +/** > + Filter memory IO before Read operation. > + > + It will return the flag to decide whether require read real MMIO. > + It can be used for emulation environment. > + > + @param[in] Width Signifies the width of the memory I/O operation. > + @param[in] Address The base address of the memory I/O operation. > + @param[in] Buffer The destination buffer to store the results. > + > +**/ > +BOOLEAN > +EFIAPI > +FilterBeforeMmIoRead ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN OUT VOID *Buffer > + ); > + > +/** > + Tracer memory IO after read operation > + > + @param[in] Width Signifies the width of the memory I/O operation. > + @param[in] Address The base address of the memory I/O operation. > + @param[in] Buffer The destination buffer to store the results. > + > +**/ > +VOID > +EFIAPI > +FilterAfterMmIoRead ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN VOID *Buffer > + ); > + > +/** > + Filter memory IO before write operation > + > + It will return the flag to decide whether require wirte real MMIO. > + It can be used for emulation environment. > + > + @param[in] Width Signifies the width of the memory I/O operation. > + @param[in] Address The base address of the memory I/O operation. > + @param[in] Buffer The source buffer from which to BeforeWrite data. > + > +**/ > +BOOLEAN > +EFIAPI > +FilterBeforeMmIoWrite ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN VOID *Buffer > + ); > + > +/** > + Tracer memory IO after write operation > + > + @param[in] Width Signifies the width of the memory I/O operation. > + @param[in] Address The base address of the memory I/O operation. > + @param[in] Buffer The source buffer from which to BeforeWrite data. > + > +**/ > +VOID > +EFIAPI > +FilterAfterMmIoWrite ( > + IN FILTER_IO_WIDTH Width, > + IN UINTN Address, > + IN VOID *Buffer > + ); > + > +/** > + Filter MSR before read operation. > + > + It will return the flag to decide whether require read real MSR. > + It can be used for emulation environment. > + > + @param Index The 8-bit Machine Specific Register index to BeforeWrite. > + @param Value The 64-bit value to BeforeRead from the Machine Specific Register. > + > +**/ > +BOOLEAN > +EFIAPI > +FilterBeforeMsrRead ( > + IN UINT32 Index, > + IN OUT UINT64 *Value > + ); > + > +/** > + Trace MSR after read operation > + > + @param Index The 8-bit Machine Specific Register index to BeforeWrite. > + @param Value The 64-bit value to BeforeRead from the Machine Specific Register. > + > +**/ > +VOID > +EFIAPI > +FilterAfterMsrRead ( > + IN UINT32 Index, > + IN UINT64 *Value > + ); > + > +/** > + Filter MSR before write operation > + > + It will return the flag to decide whether require write real MSR. > + It can be used for emulation environment. > + > + @param Index The 8-bit Machine Specific Register index to BeforeWrite. > + @param Value The 64-bit value to BeforeWrite to the Machine Specific Register. > + > +**/ > +BOOLEAN > +EFIAPI > +FilterBeforeMsrWrite ( > + IN UINT32 Index, > + IN UINT64 *Value > + ); > + > +/** > + Trace MSR after write operation > + > + @param Index The 8-bit Machine Specific Register index to BeforeWrite. > + @param Value The 64-bit value to BeforeWrite to the Machine Specific Register. > + > +**/ > +VOID > +EFIAPI > +FilterAfterMsrWrite ( > + IN UINT32 Index, > + IN UINT64 *Value > + ); > + > +#endif // __REGISTER_FILTER_LIB_H__ >