VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/XenBusDxe/GrantTable.c@ 106129

Last change on this file since 106129 was 99404, checked in by vboxsync, 20 months ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 4.7 KB
Line 
1/** @file
2 Grant Table function implementation.
3
4 Grant Table are used to grant access to certain page of the current
5 VM to an other VM.
6
7 Author: Steven Smith (sos22@cam.ac.uk)
8 Changes: Grzegorz Milos (gm281@cam.ac.uk)
9 Copyright (C) 2006, Cambridge University
10 Copyright (C) 2014, Citrix Ltd.
11
12 SPDX-License-Identifier: BSD-2-Clause-Patent
13**/
14#include "XenBusDxe.h"
15
16#include <IndustryStandard/Xen/memory.h>
17
18#include <Library/XenHypercallLib.h>
19#include <Library/SynchronizationLib.h>
20
21#include "GrantTable.h"
22
23#define NR_RESERVED_ENTRIES 8
24
25#define NR_GRANT_FRAMES (FixedPcdGet32 (PcdXenGrantFrames))
26#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * EFI_PAGE_SIZE / sizeof(grant_entry_v1_t))
27
28STATIC grant_entry_v1_t *GrantTable = NULL;
29STATIC grant_ref_t GrantList[NR_GRANT_ENTRIES];
30STATIC EFI_LOCK mGrantListLock;
31#ifdef GNT_DEBUG
32STATIC BOOLEAN GrantInUseList[NR_GRANT_ENTRIES];
33#endif
34
35STATIC
36VOID
37XenGrantTablePutFreeEntry (
38 grant_ref_t Ref
39 )
40{
41 EfiAcquireLock (&mGrantListLock);
42 #ifdef GNT_DEBUG
43 ASSERT (GrantInUseList[Ref]);
44 GrantInUseList[Ref] = FALSE;
45 #endif
46 GrantList[Ref] = GrantList[0];
47 GrantList[0] = Ref;
48 EfiReleaseLock (&mGrantListLock);
49}
50
51STATIC
52grant_ref_t
53XenGrantTableGetFreeEntry (
54 VOID
55 )
56{
57 grant_ref_t Ref;
58
59 EfiAcquireLock (&mGrantListLock);
60 Ref = GrantList[0];
61 ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES);
62 GrantList[0] = GrantList[Ref];
63 #ifdef GNT_DEBUG
64 ASSERT (!GrantInUseList[Ref]);
65 GrantInUseList[Ref] = TRUE;
66 #endif
67 EfiReleaseLock (&mGrantListLock);
68 return Ref;
69}
70
71STATIC
72grant_ref_t
73XenGrantTableGrantAccess (
74 IN domid_t DomainId,
75 IN UINTN Frame,
76 IN BOOLEAN ReadOnly
77 )
78{
79 grant_ref_t Ref;
80 UINT16 Flags;
81
82 ASSERT (GrantTable != NULL);
83 Ref = XenGrantTableGetFreeEntry ();
84 GrantTable[Ref].frame = (UINT32)Frame;
85 GrantTable[Ref].domid = DomainId;
86 MemoryFence ();
87 Flags = GTF_permit_access;
88 if (ReadOnly) {
89 Flags |= GTF_readonly;
90 }
91
92 GrantTable[Ref].flags = Flags;
93
94 return Ref;
95}
96
97STATIC
98EFI_STATUS
99XenGrantTableEndAccess (
100 grant_ref_t Ref
101 )
102{
103 UINT16 Flags, OldFlags;
104
105 ASSERT (GrantTable != NULL);
106 ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES);
107
108 OldFlags = GrantTable[Ref].flags;
109 do {
110 if ((Flags = OldFlags) & (GTF_reading | GTF_writing)) {
111 DEBUG ((DEBUG_WARN, "WARNING: g.e. still in use! (%x)\n", Flags));
112 return EFI_NOT_READY;
113 }
114
115 OldFlags = InterlockedCompareExchange16 (&GrantTable[Ref].flags, Flags, 0);
116 } while (OldFlags != Flags);
117
118 XenGrantTablePutFreeEntry (Ref);
119 return EFI_SUCCESS;
120}
121
122VOID
123XenGrantTableInit (
124 IN XENBUS_DEVICE *Dev
125 )
126{
127 xen_add_to_physmap_t Parameters;
128 INTN Index;
129 INTN ReturnCode;
130
131 #ifdef GNT_DEBUG
132 SetMem (GrantInUseList, sizeof (GrantInUseList), 1);
133 #endif
134 EfiInitializeLock (&mGrantListLock, TPL_NOTIFY);
135 for (Index = NR_RESERVED_ENTRIES; Index < NR_GRANT_ENTRIES; Index++) {
136 XenGrantTablePutFreeEntry ((grant_ref_t)Index);
137 }
138
139 GrantTable = (VOID *)(UINTN)Dev->XenIo->GrantTableAddress;
140 for (Index = 0; Index < NR_GRANT_FRAMES; Index++) {
141 Parameters.domid = DOMID_SELF;
142 Parameters.idx = Index;
143 Parameters.space = XENMAPSPACE_grant_table;
144 Parameters.gpfn = (xen_pfn_t)((UINTN)GrantTable >> EFI_PAGE_SHIFT) + Index;
145 ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);
146 if (ReturnCode != 0) {
147 DEBUG ((
148 DEBUG_ERROR,
149 "Xen GrantTable, add_to_physmap hypercall error: %Ld\n",
150 (INT64)ReturnCode
151 ));
152 }
153 }
154}
155
156VOID
157XenGrantTableDeinit (
158 XENBUS_DEVICE *Dev
159 )
160{
161 INTN ReturnCode, Index;
162 xen_remove_from_physmap_t Parameters;
163
164 if (GrantTable == NULL) {
165 return;
166 }
167
168 for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) {
169 Parameters.domid = DOMID_SELF;
170 Parameters.gpfn = (xen_pfn_t)((UINTN)GrantTable >> EFI_PAGE_SHIFT) + Index;
171 DEBUG ((
172 DEBUG_INFO,
173 "Xen GrantTable, removing %Lx\n",
174 (UINT64)Parameters.gpfn
175 ));
176 ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);
177 if (ReturnCode != 0) {
178 DEBUG ((
179 DEBUG_ERROR,
180 "Xen GrantTable, remove_from_physmap hypercall error: %Ld\n",
181 (INT64)ReturnCode
182 ));
183 }
184 }
185
186 GrantTable = NULL;
187}
188
189EFI_STATUS
190EFIAPI
191XenBusGrantAccess (
192 IN XENBUS_PROTOCOL *This,
193 IN domid_t DomainId,
194 IN UINTN Frame, // MFN
195 IN BOOLEAN ReadOnly,
196 OUT grant_ref_t *RefPtr
197 )
198{
199 *RefPtr = XenGrantTableGrantAccess (DomainId, Frame, ReadOnly);
200 return EFI_SUCCESS;
201}
202
203EFI_STATUS
204EFIAPI
205XenBusGrantEndAccess (
206 IN XENBUS_PROTOCOL *This,
207 IN grant_ref_t Ref
208 )
209{
210 return XenGrantTableEndAccess (Ref);
211}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette