]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/XenBusDxe/GrantTable.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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 22\r
ac0a286f 23#define NR_RESERVED_ENTRIES 8\r
0fd14246 24\r
ac0a286f
MK
25#define NR_GRANT_FRAMES (FixedPcdGet32 (PcdXenGrantFrames))\r
26#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * EFI_PAGE_SIZE / sizeof(grant_entry_v1_t))\r
0fd14246 27\r
ac0a286f
MK
28STATIC grant_entry_v1_t *GrantTable = NULL;\r
29STATIC grant_ref_t GrantList[NR_GRANT_ENTRIES];\r
30STATIC EFI_LOCK mGrantListLock;\r
0fd14246 31#ifdef GNT_DEBUG\r
ac0a286f 32STATIC BOOLEAN GrantInUseList[NR_GRANT_ENTRIES];\r
0fd14246
SS
33#endif\r
34\r
35STATIC\r
36VOID\r
37XenGrantTablePutFreeEntry (\r
ac0a286f 38 grant_ref_t Ref\r
0fd14246
SS
39 )\r
40{\r
41 EfiAcquireLock (&mGrantListLock);\r
ac0a286f 42 #ifdef GNT_DEBUG\r
0fd14246
SS
43 ASSERT (GrantInUseList[Ref]);\r
44 GrantInUseList[Ref] = FALSE;\r
ac0a286f 45 #endif\r
0fd14246 46 GrantList[Ref] = GrantList[0];\r
ac0a286f 47 GrantList[0] = Ref;\r
0fd14246
SS
48 EfiReleaseLock (&mGrantListLock);\r
49}\r
50\r
51STATIC\r
52grant_ref_t\r
53XenGrantTableGetFreeEntry (\r
54 VOID\r
55 )\r
56{\r
ac0a286f 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
ac0a286f 63 #ifdef GNT_DEBUG\r
0fd14246
SS
64 ASSERT (!GrantInUseList[Ref]);\r
65 GrantInUseList[Ref] = TRUE;\r
ac0a286f 66 #endif\r
0fd14246
SS
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
ac0a286f
MK
79 grant_ref_t Ref;\r
80 UINT16 Flags;\r
0fd14246
SS
81\r
82 ASSERT (GrantTable != NULL);\r
ac0a286f 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
ac0a286f 91\r
0fd14246
SS
92 GrantTable[Ref].flags = Flags;\r
93\r
94 return Ref;\r
95}\r
96\r
97STATIC\r
98EFI_STATUS\r
99XenGrantTableEndAccess (\r
ac0a286f 100 grant_ref_t Ref\r
0fd14246
SS
101 )\r
102{\r
ac0a286f 103 UINT16 Flags, OldFlags;\r
0fd14246
SS
104\r
105 ASSERT (GrantTable != NULL);\r
106 ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES);\r
107\r
108 OldFlags = GrantTable[Ref].flags;\r
109 do {\r
110 if ((Flags = OldFlags) & (GTF_reading | GTF_writing)) {\r
70d5086c 111 DEBUG ((DEBUG_WARN, "WARNING: g.e. still in use! (%x)\n", Flags));\r
0fd14246
SS
112 return EFI_NOT_READY;\r
113 }\r
ac0a286f 114\r
0fd14246
SS
115 OldFlags = InterlockedCompareExchange16 (&GrantTable[Ref].flags, Flags, 0);\r
116 } while (OldFlags != Flags);\r
117\r
118 XenGrantTablePutFreeEntry (Ref);\r
119 return EFI_SUCCESS;\r
120}\r
121\r
122VOID\r
123XenGrantTableInit (\r
d9fdfd85 124 IN XENBUS_DEVICE *Dev\r
0fd14246
SS
125 )\r
126{\r
ac0a286f
MK
127 xen_add_to_physmap_t Parameters;\r
128 INTN Index;\r
129 INTN ReturnCode;\r
0fd14246 130\r
ac0a286f
MK
131 #ifdef GNT_DEBUG\r
132 SetMem (GrantInUseList, sizeof (GrantInUseList), 1);\r
133 #endif\r
0fd14246
SS
134 EfiInitializeLock (&mGrantListLock, TPL_NOTIFY);\r
135 for (Index = NR_RESERVED_ENTRIES; Index < NR_GRANT_ENTRIES; Index++) {\r
017a4866 136 XenGrantTablePutFreeEntry ((grant_ref_t)Index);\r
0fd14246
SS
137 }\r
138\r
ac0a286f 139 GrantTable = (VOID *)(UINTN)Dev->XenIo->GrantTableAddress;\r
0fd14246
SS
140 for (Index = 0; Index < NR_GRANT_FRAMES; Index++) {\r
141 Parameters.domid = DOMID_SELF;\r
ac0a286f 142 Parameters.idx = Index;\r
0fd14246 143 Parameters.space = XENMAPSPACE_grant_table;\r
ac0a286f
MK
144 Parameters.gpfn = (xen_pfn_t)((UINTN)GrantTable >> EFI_PAGE_SHIFT) + Index;\r
145 ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);\r
0fd14246 146 if (ReturnCode != 0) {\r
ac0a286f
MK
147 DEBUG ((\r
148 DEBUG_ERROR,\r
6394c35a 149 "Xen GrantTable, add_to_physmap hypercall error: %Ld\n",\r
ac0a286f
MK
150 (INT64)ReturnCode\r
151 ));\r
0fd14246
SS
152 }\r
153 }\r
154}\r
155\r
156VOID\r
157XenGrantTableDeinit (\r
ac0a286f 158 XENBUS_DEVICE *Dev\r
0fd14246
SS
159 )\r
160{\r
ac0a286f
MK
161 INTN ReturnCode, Index;\r
162 xen_remove_from_physmap_t Parameters;\r
0fd14246
SS
163\r
164 if (GrantTable == NULL) {\r
165 return;\r
166 }\r
167\r
168 for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) {\r
169 Parameters.domid = DOMID_SELF;\r
ac0a286f
MK
170 Parameters.gpfn = (xen_pfn_t)((UINTN)GrantTable >> EFI_PAGE_SHIFT) + Index;\r
171 DEBUG ((\r
172 DEBUG_INFO,\r
173 "Xen GrantTable, removing %Lx\n",\r
174 (UINT64)Parameters.gpfn\r
175 ));\r
bbc3758a 176 ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);\r
0fd14246 177 if (ReturnCode != 0) {\r
ac0a286f
MK
178 DEBUG ((\r
179 DEBUG_ERROR,\r
6394c35a 180 "Xen GrantTable, remove_from_physmap hypercall error: %Ld\n",\r
ac0a286f
MK
181 (INT64)ReturnCode\r
182 ));\r
0fd14246
SS
183 }\r
184 }\r
ac0a286f 185\r
0fd14246
SS
186 GrantTable = NULL;\r
187}\r
188\r
189EFI_STATUS\r
190EFIAPI\r
191XenBusGrantAccess (\r
ac0a286f
MK
192 IN XENBUS_PROTOCOL *This,\r
193 IN domid_t DomainId,\r
194 IN UINTN Frame, // MFN\r
195 IN BOOLEAN ReadOnly,\r
196 OUT grant_ref_t *RefPtr\r
0fd14246
SS
197 )\r
198{\r
199 *RefPtr = XenGrantTableGrantAccess (DomainId, Frame, ReadOnly);\r
200 return EFI_SUCCESS;\r
201}\r
202\r
203EFI_STATUS\r
204EFIAPI\r
205XenBusGrantEndAccess (\r
206 IN XENBUS_PROTOCOL *This,\r
207 IN grant_ref_t Ref\r
208 )\r
209{\r
210 return XenGrantTableEndAccess (Ref);\r
211}\r