2 Grant Table function implementation.
4 Grant Table are used to grant access to certain page of the current
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.
12 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include "XenBusDxe.h"
16 #include <IndustryStandard/Xen/memory.h>
18 #include <Library/XenHypercallLib.h>
19 #include <Library/SynchronizationLib.h>
21 #include "GrantTable.h"
23 #define NR_RESERVED_ENTRIES 8
25 #define NR_GRANT_FRAMES (FixedPcdGet32 (PcdXenGrantFrames))
26 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * EFI_PAGE_SIZE / sizeof(grant_entry_v1_t))
28 STATIC grant_entry_v1_t
*GrantTable
= NULL
;
29 STATIC grant_ref_t GrantList
[NR_GRANT_ENTRIES
];
30 STATIC EFI_LOCK mGrantListLock
;
32 STATIC BOOLEAN GrantInUseList
[NR_GRANT_ENTRIES
];
37 XenGrantTablePutFreeEntry (
41 EfiAcquireLock (&mGrantListLock
);
43 ASSERT (GrantInUseList
[Ref
]);
44 GrantInUseList
[Ref
] = FALSE
;
46 GrantList
[Ref
] = GrantList
[0];
48 EfiReleaseLock (&mGrantListLock
);
53 XenGrantTableGetFreeEntry (
59 EfiAcquireLock (&mGrantListLock
);
61 ASSERT (Ref
>= NR_RESERVED_ENTRIES
&& Ref
< NR_GRANT_ENTRIES
);
62 GrantList
[0] = GrantList
[Ref
];
64 ASSERT (!GrantInUseList
[Ref
]);
65 GrantInUseList
[Ref
] = TRUE
;
67 EfiReleaseLock (&mGrantListLock
);
73 XenGrantTableGrantAccess (
82 ASSERT (GrantTable
!= NULL
);
83 Ref
= XenGrantTableGetFreeEntry ();
84 GrantTable
[Ref
].frame
= (UINT32
)Frame
;
85 GrantTable
[Ref
].domid
= DomainId
;
87 Flags
= GTF_permit_access
;
89 Flags
|= GTF_readonly
;
91 GrantTable
[Ref
].flags
= Flags
;
98 XenGrantTableEndAccess (
102 UINT16 Flags
, OldFlags
;
104 ASSERT (GrantTable
!= NULL
);
105 ASSERT (Ref
>= NR_RESERVED_ENTRIES
&& Ref
< NR_GRANT_ENTRIES
);
107 OldFlags
= GrantTable
[Ref
].flags
;
109 if ((Flags
= OldFlags
) & (GTF_reading
| GTF_writing
)) {
110 DEBUG ((DEBUG_WARN
, "WARNING: g.e. still in use! (%x)\n", Flags
));
111 return EFI_NOT_READY
;
113 OldFlags
= InterlockedCompareExchange16 (&GrantTable
[Ref
].flags
, Flags
, 0);
114 } while (OldFlags
!= Flags
);
116 XenGrantTablePutFreeEntry (Ref
);
122 IN XENBUS_DEVICE
*Dev
125 xen_add_to_physmap_t Parameters
;
130 SetMem(GrantInUseList
, sizeof (GrantInUseList
), 1);
132 EfiInitializeLock (&mGrantListLock
, TPL_NOTIFY
);
133 for (Index
= NR_RESERVED_ENTRIES
; Index
< NR_GRANT_ENTRIES
; Index
++) {
134 XenGrantTablePutFreeEntry ((grant_ref_t
)Index
);
137 GrantTable
= (VOID
*)(UINTN
) Dev
->XenIo
->GrantTableAddress
;
138 for (Index
= 0; Index
< NR_GRANT_FRAMES
; Index
++) {
139 Parameters
.domid
= DOMID_SELF
;
140 Parameters
.idx
= Index
;
141 Parameters
.space
= XENMAPSPACE_grant_table
;
142 Parameters
.gpfn
= (xen_pfn_t
) ((UINTN
) GrantTable
>> EFI_PAGE_SHIFT
) + Index
;
143 ReturnCode
= XenHypercallMemoryOp (XENMEM_add_to_physmap
, &Parameters
);
144 if (ReturnCode
!= 0) {
146 "Xen GrantTable, add_to_physmap hypercall error: %Ld\n",
153 XenGrantTableDeinit (
157 INTN ReturnCode
, Index
;
158 xen_remove_from_physmap_t Parameters
;
160 if (GrantTable
== NULL
) {
164 for (Index
= NR_GRANT_FRAMES
- 1; Index
>= 0; Index
--) {
165 Parameters
.domid
= DOMID_SELF
;
166 Parameters
.gpfn
= (xen_pfn_t
) ((UINTN
) GrantTable
>> EFI_PAGE_SHIFT
) + Index
;
167 DEBUG ((DEBUG_INFO
, "Xen GrantTable, removing %Lx\n",
168 (UINT64
)Parameters
.gpfn
));
169 ReturnCode
= XenHypercallMemoryOp (XENMEM_remove_from_physmap
, &Parameters
);
170 if (ReturnCode
!= 0) {
172 "Xen GrantTable, remove_from_physmap hypercall error: %Ld\n",
182 IN XENBUS_PROTOCOL
*This
,
184 IN UINTN Frame
, // MFN
186 OUT grant_ref_t
*RefPtr
189 *RefPtr
= XenGrantTableGrantAccess (DomainId
, Frame
, ReadOnly
);
195 XenBusGrantEndAccess (
196 IN XENBUS_PROTOCOL
*This
,
200 return XenGrantTableEndAccess (Ref
);