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 /* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
26 #define NR_GRANT_FRAMES 4
27 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * EFI_PAGE_SIZE / sizeof(grant_entry_v1_t))
29 STATIC grant_entry_v1_t
*GrantTable
= NULL
;
30 STATIC grant_ref_t GrantList
[NR_GRANT_ENTRIES
];
31 STATIC EFI_LOCK mGrantListLock
;
33 STATIC BOOLEAN GrantInUseList
[NR_GRANT_ENTRIES
];
38 XenGrantTablePutFreeEntry (
42 EfiAcquireLock (&mGrantListLock
);
44 ASSERT (GrantInUseList
[Ref
]);
45 GrantInUseList
[Ref
] = FALSE
;
47 GrantList
[Ref
] = GrantList
[0];
49 EfiReleaseLock (&mGrantListLock
);
54 XenGrantTableGetFreeEntry (
60 EfiAcquireLock (&mGrantListLock
);
62 ASSERT (Ref
>= NR_RESERVED_ENTRIES
&& Ref
< NR_GRANT_ENTRIES
);
63 GrantList
[0] = GrantList
[Ref
];
65 ASSERT (!GrantInUseList
[Ref
]);
66 GrantInUseList
[Ref
] = TRUE
;
68 EfiReleaseLock (&mGrantListLock
);
74 XenGrantTableGrantAccess (
83 ASSERT (GrantTable
!= NULL
);
84 Ref
= XenGrantTableGetFreeEntry ();
85 GrantTable
[Ref
].frame
= (UINT32
)Frame
;
86 GrantTable
[Ref
].domid
= DomainId
;
88 Flags
= GTF_permit_access
;
90 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 ((EFI_D_WARN
, "WARNING: g.e. still in use! (%x)\n", Flags
));
112 return EFI_NOT_READY
;
114 OldFlags
= InterlockedCompareExchange16 (&GrantTable
[Ref
].flags
, Flags
, 0);
115 } while (OldFlags
!= Flags
);
117 XenGrantTablePutFreeEntry (Ref
);
123 IN XENBUS_DEVICE
*Dev
126 xen_add_to_physmap_t Parameters
;
131 SetMem(GrantInUseList
, sizeof (GrantInUseList
), 1);
133 EfiInitializeLock (&mGrantListLock
, TPL_NOTIFY
);
134 for (Index
= NR_RESERVED_ENTRIES
; Index
< NR_GRANT_ENTRIES
; Index
++) {
135 XenGrantTablePutFreeEntry ((grant_ref_t
)Index
);
138 GrantTable
= (VOID
*)(UINTN
) Dev
->XenIo
->GrantTableAddress
;
139 for (Index
= 0; Index
< NR_GRANT_FRAMES
; Index
++) {
140 Parameters
.domid
= DOMID_SELF
;
141 Parameters
.idx
= Index
;
142 Parameters
.space
= XENMAPSPACE_grant_table
;
143 Parameters
.gpfn
= (xen_pfn_t
) ((UINTN
) GrantTable
>> EFI_PAGE_SHIFT
) + Index
;
144 ReturnCode
= XenHypercallMemoryOp (XENMEM_add_to_physmap
, &Parameters
);
145 if (ReturnCode
!= 0) {
147 "Xen GrantTable, add_to_physmap hypercall error: %Ld\n",
154 XenGrantTableDeinit (
158 INTN ReturnCode
, Index
;
159 xen_remove_from_physmap_t Parameters
;
161 if (GrantTable
== NULL
) {
165 for (Index
= NR_GRANT_FRAMES
- 1; Index
>= 0; Index
--) {
166 Parameters
.domid
= DOMID_SELF
;
167 Parameters
.gpfn
= (xen_pfn_t
) ((UINTN
) GrantTable
>> EFI_PAGE_SHIFT
) + Index
;
168 DEBUG ((EFI_D_INFO
, "Xen GrantTable, removing %Lx\n",
169 (UINT64
)Parameters
.gpfn
));
170 ReturnCode
= XenHypercallMemoryOp (XENMEM_remove_from_physmap
, &Parameters
);
171 if (ReturnCode
!= 0) {
173 "Xen GrantTable, remove_from_physmap hypercall error: %Ld\n",
183 IN XENBUS_PROTOCOL
*This
,
185 IN UINTN Frame
, // MFN
187 OUT grant_ref_t
*RefPtr
190 *RefPtr
= XenGrantTableGrantAccess (DomainId
, Frame
, ReadOnly
);
196 XenBusGrantEndAccess (
197 IN XENBUS_PROTOCOL
*This
,
201 return XenGrantTableEndAccess (Ref
);