From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com []) by mx.groups.io with SMTP id smtpd.web11.3423.1576133639897144390 for ; Wed, 11 Dec 2019 22:54:01 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: ray.ni@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Dec 2019 22:54:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,304,1571727600"; d="scan'208";a="207969671" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga008.jf.intel.com with ESMTP; 11 Dec 2019 22:54:00 -0800 Received: from fmsmsx152.amr.corp.intel.com (10.18.125.5) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 11 Dec 2019 22:53:59 -0800 Received: from shsmsx154.ccr.corp.intel.com (10.239.6.54) by FMSMSX152.amr.corp.intel.com (10.18.125.5) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 11 Dec 2019 22:53:59 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.90]) by SHSMSX154.ccr.corp.intel.com ([169.254.7.71]) with mapi id 14.03.0439.000; Thu, 12 Dec 2019 14:53:57 +0800 From: "Ni, Ray" To: Tom Lendacky , "devel@edk2.groups.io" CC: "Justen, Jordan L" , Laszlo Ersek , Ard Biesheuvel , "Kinney, Michael D" , "Gao, Liming" , "Dong, Eric" , Brijesh Singh Subject: Re: [RFC PATCH v3 22/43] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE events Thread-Topic: [RFC PATCH v3 22/43] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE events Thread-Index: AQHVn945INs3EQ1sjkiw/Ufd2xjeKae2LLgA Date: Thu, 12 Dec 2019 06:53:57 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C399A29@SHSMSX104.ccr.corp.intel.com> References: In-Reply-To: Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiY2JkZDE4NmYtY2U3Zi00MTUyLTgwNjktMWUzMjEwMjFmYWEyIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiSGRPWGtBcGQ1QXFoUXVYbHpUa3NJNTBBNGh4VVwvQnB3ZTBScXVSU0dFTU5UclRRMmFvY3AxSnBxeFlXeU56SWcifQ== x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Tom, Why all DR registers are not pushed to stack in VC handler? I thought only DR7 pushing is skipped. Thanks, Ray > -----Original Message----- > From: Tom Lendacky > Sent: Thursday, November 21, 2019 4:07 AM > To: devel@edk2.groups.io > Cc: Justen, Jordan L ; Laszlo Ersek ; Ard Biesheuvel > ; Kinney, Michael D ; Gao, Liming ; Dong, > Eric ; Ni, Ray ; Brijesh Singh > Subject: [RFC PATCH v3 22/43] UefiCpuPkg/CpuExceptionHandler: Add support= for DR7 Read/Write NAE events >=20 > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2198 >=20 > Under SEV-ES, a DR7 read or write intercept generates a #VC exception. > The #VC handler must provide special support to the guest for this. On > a DR7 write, the #VC handler must cache the value and issue a VMGEXIT > to notify the hypervisor of the write. However, the #VC handler must > not actually set the value of the DR7 register. On a DR7 read, the #VC > handler must return the cached value of the DR7 register to the guest. > VMGEXIT is not invoked for a DR7 register read. >=20 > To avoid exception recursion, a #VC exception will not try to read and > push the actual debug registers into the EFI_SYSTEM_CONTEXT_X64 struct > and instead push zeroes. The #VC exception handler does not make use of > the debug registers from saved context. >=20 > Cc: Eric Dong > Cc: Ray Ni > Cc: Laszlo Ersek > Signed-off-by: Tom Lendacky > --- > .../X64/AMDSevVcCommon.c | 68 +++++++++++++++++++ > .../X64/ExceptionHandlerAsm.nasm | 15 ++++ > 2 files changed, 83 insertions(+) >=20 > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon= .c > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c > index 1d7c34e7e442..22393f72d795 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c > @@ -13,6 +13,12 @@ >=20 > #define CR4_OSXSAVE (1 << 18) >=20 > +#define DR7_RESET_VALUE 0x400 > +typedef struct { > + BOOLEAN Dr7Cached; > + UINT64 Dr7; > +} SEV_ES_PER_CPU_DATA; > + > typedef enum { > LongMode64Bit =3D 0, > LongModeCompat32Bit, > @@ -1081,6 +1087,60 @@ RdtscExit ( > return 0; > } >=20 > +STATIC > +UINTN > +Dr7WriteExit ( > + GHCB *Ghcb, > + EFI_SYSTEM_CONTEXT_X64 *Regs, > + SEV_ES_INSTRUCTION_DATA *InstructionData > + ) > +{ > + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext =3D &InstructionData->Ext; > + SEV_ES_PER_CPU_DATA *SevEsData =3D (SEV_ES_PER_CPU_DATA *) = (Ghcb + 1); > + INTN *Register; > + UINTN Status; > + > + DecodeModRm (Regs, InstructionData); > + > + /* MOV DRn always treats MOD =3D=3D 3 no matter how encoded */ > + Register =3D GetRegisterPointer (Regs, Ext->ModRm.Rm); > + > + /* Using a value of 0 for ExitInfo1 means RAX holds the value */ > + Ghcb->SaveArea.Rax =3D *Register; > + GhcbSetRegValid (Ghcb, GhcbRax); > + > + Status =3D VmgExit (Ghcb, SvmExitDr7Write, 0, 0); > + if (Status) { > + return Status; > + } > + > + SevEsData->Dr7 =3D *Register; > + SevEsData->Dr7Cached =3D TRUE; > + > + return 0; > +} > + > +STATIC > +UINTN > +Dr7ReadExit ( > + GHCB *Ghcb, > + EFI_SYSTEM_CONTEXT_X64 *Regs, > + SEV_ES_INSTRUCTION_DATA *InstructionData > + ) > +{ > + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext =3D &InstructionData->Ext; > + SEV_ES_PER_CPU_DATA *SevEsData =3D (SEV_ES_PER_CPU_DATA *) = (Ghcb + 1); > + INTN *Register; > + > + DecodeModRm (Regs, InstructionData); > + > + /* MOV DRn always treats MOD =3D=3D 3 no matter how encoded */ > + Register =3D GetRegisterPointer (Regs, Ext->ModRm.Rm); > + *Register =3D (SevEsData->Dr7Cached) ? SevEsData->Dr7 : DR7_RESET_VALU= E; > + > + return 0; > +} > + > UINTN > DoVcCommon ( > GHCB *Ghcb, > @@ -1097,6 +1157,14 @@ DoVcCommon ( >=20 > ExitCode =3D Regs->ExceptionData; > switch (ExitCode) { > + case SvmExitDr7Read: > + NaeExit =3D Dr7ReadExit; > + break; > + > + case SvmExitDr7Write: > + NaeExit =3D Dr7WriteExit; > + break; > + > case SvmExitRdtsc: > NaeExit =3D RdtscExit; > break; > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandl= erAsm.nasm > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm > index 19198f273137..a0549f7ae6bd 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.n= asm > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.n= asm > @@ -225,6 +225,9 @@ HasErrorCode: > push rax >=20 > ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; > + cmp qword [rbp + 8], 29 > + je VcDebugRegs ; For SEV-ES (#VC) Debug registers igno= red > + > mov rax, dr7 > push rax > mov rax, dr6 > @@ -237,7 +240,19 @@ HasErrorCode: > push rax > mov rax, dr0 > push rax > + jmp DrFinish >=20 > +VcDebugRegs: > +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exc= eption recursion > + xor rax, rax > + push rax > + push rax > + push rax > + push rax > + push rax > + push rax > + > +DrFinish: > ;; FX_SAVE_STATE_X64 FxSaveState; > sub rsp, 512 > mov rdi, rsp > -- > 2.17.1