TianoCore EDK2 master
Loading...
Searching...
No Matches
GrantTable.c
Go to the documentation of this file.
1
14#include "XenBusDxe.h"
15
16#include <IndustryStandard/Xen/memory.h>
17
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
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
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
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
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
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
190EFIAPI
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
204EFIAPI
206 IN XENBUS_PROTOCOL *This,
207 IN grant_ref_t Ref
208 )
209{
210 return XenGrantTableEndAccess (Ref);
211}
UINT64 UINTN
INT64 INTN
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
EFI_STATUS EFIAPI XenBusGrantEndAccess(IN XENBUS_PROTOCOL *This, IN grant_ref_t Ref)
Definition: GrantTable.c:205
EFI_STATUS EFIAPI XenBusGrantAccess(IN XENBUS_PROTOCOL *This, IN domid_t DomainId, IN UINTN Frame, IN BOOLEAN ReadOnly, OUT grant_ref_t *RefPtr)
Definition: GrantTable.c:191
VOID XenGrantTableInit(IN XENBUS_DEVICE *Dev)
Definition: GrantTable.c:123
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT16 EFIAPI InterlockedCompareExchange16(IN OUT volatile UINT16 *Value, IN UINT16 CompareValue, IN UINT16 ExchangeValue)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:434
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: UefiLib.c:405
INTN EFIAPI XenHypercallMemoryOp(IN UINTN Operation, IN OUT VOID *Arguments)
Definition: XenHypercall.c:65
Definition: grant_table.h:115