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
;
92 GrantTable
[Ref
].flags
= Flags
;
99 XenGrantTableEndAccess (
103 UINT16 Flags
, OldFlags
;
105 ASSERT (GrantTable
!= NULL
);
106 ASSERT (Ref
>= NR_RESERVED_ENTRIES
&& Ref
< NR_GRANT_ENTRIES
);
108 OldFlags
= GrantTable
[Ref
].flags
;
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
;
115 OldFlags
= InterlockedCompareExchange16 (&GrantTable
[Ref
].flags
, Flags
, 0);
116 } while (OldFlags
!= Flags
);
118 XenGrantTablePutFreeEntry (Ref
);
124 IN XENBUS_DEVICE
*Dev
127 xen_add_to_physmap_t Parameters
;
132 SetMem (GrantInUseList
, sizeof (GrantInUseList
), 1);
134 EfiInitializeLock (&mGrantListLock
, TPL_NOTIFY
);
135 for (Index
= NR_RESERVED_ENTRIES
; Index
< NR_GRANT_ENTRIES
; Index
++) {
136 XenGrantTablePutFreeEntry ((grant_ref_t
)Index
);
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) {
149 "Xen GrantTable, add_to_physmap hypercall error: %Ld\n",
157 XenGrantTableDeinit (
161 INTN ReturnCode
, Index
;
162 xen_remove_from_physmap_t Parameters
;
164 if (GrantTable
== NULL
) {
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
;
173 "Xen GrantTable, removing %Lx\n",
174 (UINT64
)Parameters
.gpfn
176 ReturnCode
= XenHypercallMemoryOp (XENMEM_remove_from_physmap
, &Parameters
);
177 if (ReturnCode
!= 0) {
180 "Xen GrantTable, remove_from_physmap hypercall error: %Ld\n",
192 IN XENBUS_PROTOCOL
*This
,
194 IN UINTN Frame
, // MFN
196 OUT grant_ref_t
*RefPtr
199 *RefPtr
= XenGrantTableGrantAccess (DomainId
, Frame
, ReadOnly
);
205 XenBusGrantEndAccess (
206 IN XENBUS_PROTOCOL
*This
,
210 return XenGrantTableEndAccess (Ref
);