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