From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from userp2120.oracle.com (userp2120.oracle.com [156.151.31.85]) by mx.groups.io with SMTP id smtpd.web12.15186.1585152486487803708 for ; Wed, 25 Mar 2020 09:08:06 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@oracle.com header.s=corp-2020-01-29 header.b=voYwuSq4; spf=pass (domain: oracle.com, ip: 156.151.31.85, mailfrom: liran.alon@oracle.com) Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 02PG4HmV133082; Wed, 25 Mar 2020 16:08:06 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2020-01-29; bh=iz1Mh3VgGgvKuiBUVn+IhoBdp0/pu4AbqmxSO06HRic=; b=voYwuSq4QSK5X3H4A0VTCX+EVyN/8vtidp0d25fHy51BEHor4ZuENDBpy3eZqe3gy/ro adVNmk33Ha1YuArw21K2zEzxV5rP43XM6ApOcpAWWNWXwiZEvB9E+zgt+8MyTvXVBDmk Y8CBul9Rk6nWYIELtj1xTV8Ki50gKifKSsk2T5XDbNaIi/5wSK0HG4+7Zy+t2oR6pGxr Fke0Am2dGv8iqU2unClLU9CkJhVLPiimu3XvpvD/3GTSidqxs2ep029gbmBhArQ9061T HqnSJGdbPLB/4VBM/aYRjmUlA+9mW4K9xjhGDpilpm8KwmdoP0VWL7KVcBT2JWrzCtJP ew== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2120.oracle.com with ESMTP id 3005kv9phu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 25 Mar 2020 16:08:06 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 02PG7efr182101; Wed, 25 Mar 2020 16:08:05 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3020.oracle.com with ESMTP id 3003gj0smq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 25 Mar 2020 16:08:05 +0000 Received: from abhmp0020.oracle.com (abhmp0020.oracle.com [141.146.116.26]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 02PG84m3031997; Wed, 25 Mar 2020 16:08:05 GMT Received: from spark.ravello.local (/213.57.127.2) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 25 Mar 2020 09:08:04 -0700 From: "Liran Alon" To: devel@edk2.groups.io, lersek@redhat.com Cc: nikita.leshchenko@oracle.com, aaron.young@oracle.com, jordan.l.justen@intel.com, ard.biesheuvel@linaro.org, Liran Alon Subject: [PATCH v2 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings Date: Wed, 25 Mar 2020 18:10:01 +0200 Message-Id: <20200325161005.16743-14-liran.alon@oracle.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200325161005.16743-1-liran.alon@oracle.com> References: <20200325161005.16743-1-liran.alon@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9571 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 mlxlogscore=999 bulkscore=0 phishscore=0 adultscore=0 spamscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2003250129 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9571 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 bulkscore=0 phishscore=0 suspectscore=0 impostorscore=0 spamscore=0 adultscore=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 mlxscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2003250128 Content-Transfer-Encoding: 8bit These rings are shared memory buffers between host and device in which a cyclic buffer is managed to send request descriptors from host to device and receive completion descriptors from device to host. Note that because device may be constrained by IOMMU or guest may be run under AMD SEV, we make sure to map these rings to device by using PciIo->Map(). Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567 Signed-off-by: Liran Alon --- OvmfPkg/PvScsiDxe/PvScsi.c | 269 +++++++++++++++++++++++++++++++++++++ OvmfPkg/PvScsiDxe/PvScsi.h | 17 +++ 2 files changed, 286 insertions(+) diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c index 831a78cc18c7..59863f83c60c 100644 --- a/OvmfPkg/PvScsiDxe/PvScsi.c +++ b/OvmfPkg/PvScsiDxe/PvScsi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "PvScsi.h" @@ -413,6 +414,264 @@ PvScsiRestorePciAttributes ( ); } +STATIC +EFI_STATUS +PvScsiAllocatePages ( + IN PVSCSI_DEV *Dev, + IN UINTN Pages, + IN OUT VOID **HostAddress + ) +{ + return Dev->PciIo->AllocateBuffer ( + Dev->PciIo, + AllocateAnyPages, + EfiBootServicesData, + Pages, + HostAddress, + EFI_PCI_ATTRIBUTE_MEMORY_CACHED + ); +} + +STATIC +VOID +PvScsiFreePages ( + IN PVSCSI_DEV *Dev, + IN UINTN Pages, + IN VOID *HostAddress + ) +{ + Dev->PciIo->FreeBuffer ( + Dev->PciIo, + Pages, + HostAddress + ); +} + +STATIC +EFI_STATUS +PvScsiMapBuffer ( + IN PVSCSI_DEV *Dev, + IN EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation, + IN VOID *HostAddress, + IN UINTN NumberOfBytes, + OUT PVSCSI_DMA_DESC *DmaDesc + ) +{ + EFI_STATUS Status; + UINTN BytesMapped; + + BytesMapped = NumberOfBytes; + Status = Dev->PciIo->Map ( + Dev->PciIo, + PciIoOperation, + HostAddress, + &BytesMapped, + &DmaDesc->DeviceAddress, + &DmaDesc->Mapping + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (BytesMapped != NumberOfBytes) { + Status = EFI_OUT_OF_RESOURCES; + goto Unmap; + } + + return EFI_SUCCESS; + +Unmap: + Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping); + + return Status; +} + +STATIC +VOID +PvScsiUnmapBuffer ( + IN PVSCSI_DEV *Dev, + IN OUT PVSCSI_DMA_DESC *DmaDesc) +{ + Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping); +} + +STATIC +EFI_STATUS +PvScsiAllocateSharedPages ( + IN PVSCSI_DEV *Dev, + IN UINTN Pages, + IN EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation, + OUT VOID **HostAddress, + OUT PVSCSI_DMA_DESC *DmaDesc + ) +{ + EFI_STATUS Status; + + Status = PvScsiAllocatePages (Dev, Pages, HostAddress); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PvScsiMapBuffer ( + Dev, + PciIoOperation, + *HostAddress, + EFI_PAGES_TO_SIZE (Pages), + DmaDesc + ); + if (EFI_ERROR (Status)) { + goto FreePages; + } + + return EFI_SUCCESS; + +FreePages: + PvScsiFreePages (Dev, Pages, *HostAddress); + + return Status; +} + +STATIC +VOID +PvScsiFreeSharedPages ( + IN PVSCSI_DEV *Dev, + IN UINTN Pages, + IN OUT VOID *HostAddress, + IN OUT PVSCSI_DMA_DESC *DmaDesc + ) +{ + PvScsiUnmapBuffer (Dev, DmaDesc); + PvScsiFreePages (Dev, Pages, HostAddress); +} + +STATIC +EFI_STATUS +PvScsiInitRings ( + IN OUT PVSCSI_DEV *Dev + ) +{ + EFI_STATUS Status; + PVSCSI_CMD_DESC_SETUP_RINGS Cmd; + + Status = PvScsiAllocateSharedPages ( + Dev, + 1, + EfiPciIoOperationBusMasterCommonBuffer, + (VOID **)&Dev->RingDesc.RingState, + &Dev->RingDesc.RingStateDmaDesc + ); + if (EFI_ERROR (Status)) { + return Status; + } + ZeroMem (Dev->RingDesc.RingState, EFI_PAGE_SIZE); + + Status = PvScsiAllocateSharedPages ( + Dev, + 1, + EfiPciIoOperationBusMasterCommonBuffer, + (VOID **)&Dev->RingDesc.RingReqs, + &Dev->RingDesc.RingReqsDmaDesc + ); + if (EFI_ERROR (Status)) { + goto FreeRingState; + } + ZeroMem (Dev->RingDesc.RingReqs, EFI_PAGE_SIZE); + + Status = PvScsiAllocateSharedPages ( + Dev, + 1, + EfiPciIoOperationBusMasterCommonBuffer, + (VOID **)&Dev->RingDesc.RingCmps, + &Dev->RingDesc.RingCmpsDmaDesc + ); + if (EFI_ERROR (Status)) { + goto FreeRingReqs; + } + ZeroMem (Dev->RingDesc.RingCmps, EFI_PAGE_SIZE); + + ZeroMem (&Cmd, sizeof (Cmd)); + Cmd.ReqRingNumPages = 1; + Cmd.CmpRingNumPages = 1; + Cmd.RingsStatePPN = RShiftU64 ( + (UINT64)Dev->RingDesc.RingStateDmaDesc.DeviceAddress, + EFI_PAGE_SHIFT + ); + Cmd.ReqRingPPNs[0] = RShiftU64 ( + (UINT64)Dev->RingDesc.RingReqsDmaDesc.DeviceAddress, + EFI_PAGE_SHIFT + ); + Cmd.CmpRingPPNs[0] = RShiftU64 ( + (UINT64)Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress, + EFI_PAGE_SHIFT + ); + + Status = PvScsiWriteCmdDesc ( + Dev, + PvScsiCmdSetupRings, + (UINT32 *)&Cmd, + sizeof (Cmd) / sizeof (UINT32) + ); + if (EFI_ERROR (Status)) { + goto FreeRingCmps; + } + + return EFI_SUCCESS; + +FreeRingCmps: + PvScsiFreeSharedPages ( + Dev, + 1, + Dev->RingDesc.RingCmps, + &Dev->RingDesc.RingCmpsDmaDesc + ); + +FreeRingReqs: + PvScsiFreeSharedPages ( + Dev, + 1, + Dev->RingDesc.RingReqs, + &Dev->RingDesc.RingReqsDmaDesc + ); + +FreeRingState: + PvScsiFreeSharedPages ( + Dev, + 1, + Dev->RingDesc.RingState, + &Dev->RingDesc.RingStateDmaDesc + ); + + return Status; +} + +STATIC +VOID +PvScsiFreeRings ( + IN OUT PVSCSI_DEV *Dev + ) +{ + PvScsiFreeSharedPages ( + Dev, + 1, + Dev->RingDesc.RingCmps, + &Dev->RingDesc.RingCmpsDmaDesc + ); + + PvScsiFreeSharedPages ( + Dev, + 1, + Dev->RingDesc.RingReqs, + &Dev->RingDesc.RingReqsDmaDesc + ); + + PvScsiFreeSharedPages ( + Dev, + 1, + Dev->RingDesc.RingState, + &Dev->RingDesc.RingStateDmaDesc + ); +} + STATIC EFI_STATUS PvScsiInit ( @@ -443,6 +702,14 @@ PvScsiInit ( goto RestorePciAttributes; } + // + // Init PVSCSI rings + // + Status = PvScsiInitRings (Dev); + if (EFI_ERROR (Status)) { + goto RestorePciAttributes; + } + // // Populate the exported interface's attributes // @@ -486,6 +753,8 @@ PvScsiUninit ( IN OUT PVSCSI_DEV *Dev ) { + PvScsiFreeRings (Dev); + PvScsiRestorePciAttributes (Dev); } diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h index 5f611dbbc98c..6d23b6e1eccf 100644 --- a/OvmfPkg/PvScsiDxe/PvScsi.h +++ b/OvmfPkg/PvScsiDxe/PvScsi.h @@ -15,12 +15,29 @@ #include #include +typedef struct { + EFI_PHYSICAL_ADDRESS DeviceAddress; + VOID *Mapping; +} PVSCSI_DMA_DESC; + +typedef struct { + PVSCSI_RINGS_STATE *RingState; + PVSCSI_DMA_DESC RingStateDmaDesc; + + PVSCSI_RING_REQ_DESC *RingReqs; + PVSCSI_DMA_DESC RingReqsDmaDesc; + + PVSCSI_RING_CMP_DESC *RingCmps; + PVSCSI_DMA_DESC RingCmpsDmaDesc; +} PVSCSI_RING_DESC; + #define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S') typedef struct { UINT32 Signature; EFI_PCI_IO_PROTOCOL *PciIo; UINT64 OriginalPciAttributes; + PVSCSI_RING_DESC RingDesc; UINT8 MaxTarget; UINT8 MaxLun; EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru; -- 2.20.1