Skip to content

Commit f7d88d4

Browse files
committed
many: fix several memory issues, fix issue with filesystem transactions, fix issues in SHM buffers when exporting buffers with weird offsets
1 parent 0b8aa1b commit f7d88d4

22 files changed

Lines changed: 411 additions & 264 deletions

File tree

kernel/handle.c

Lines changed: 113 additions & 119 deletions
Large diffs are not rendered by default.

kernel/include/handle.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ AcquireHandleOfType(
110110
*/
111111
KERNELAPI void* KERNELABI
112112
LookupHandleOfType(
113-
_In_ uuid_t handleId,
114-
_In_ HandleType_t handleType);
113+
_In_ uuid_t ID,
114+
_In_ HandleType_t type);
115115

116116
#endif //! __HANDLE_H__

kernel/memory/heap.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,7 @@ MemoryCacheAllocate(
720720
if (Slab->NumberOfFreeObjects == 1) {
721721
list_remove(&Cache->PartialSlabs, Element);
722722
}
723-
}
724-
else {
723+
} else {
725724
Element = list_front(&Cache->FreeSlabs);
726725
assert(Element != NULL);
727726

@@ -741,8 +740,7 @@ MemoryCacheAllocate(
741740
Cache->NumberOfFreeObjects--;
742741

743742
Allocated = MEMORY_SLAB_ELEMENT(Cache, Slab, Index);
744-
}
745-
else if (!(Cache->Flags & HEAP_SINGLE_SLAB)) {
743+
} else if (!(Cache->Flags & HEAP_SINGLE_SLAB)) {
746744
Slab = __SlabCreate(Cache);
747745
if (!Slab) {
748746
MutexUnlock(&Cache->SyncObject);
@@ -755,15 +753,13 @@ MemoryCacheAllocate(
755753

756754
if (!Slab->NumberOfFreeObjects) {
757755
list_append(&Cache->FullSlabs, &Slab->Header);
758-
}
759-
else {
756+
} else {
760757
list_append(&Cache->PartialSlabs, &Slab->Header);
761758
Cache->NumberOfFreeObjects += (Cache->ObjectCount - 1);
762759
}
763760

764761
Allocated = MEMORY_SLAB_ELEMENT(Cache, Slab, Index);
765-
}
766-
else {
762+
} else {
767763
ERROR("[heap] [%s] ran out of objects %i/%i", Cache->Name,
768764
Cache->NumberOfFreeObjects, Cache->ObjectCount);
769765
Allocated = NULL;

kernel/memory/ms_shm.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ __UpdateMapping(
10381038
);
10391039
}
10401040

1041-
oserr_t
1041+
static oserr_t
10421042
__CreateMapping(
10431043
_In_ struct SHMBuffer* shmBuffer,
10441044
_In_ size_t offset,
@@ -1073,7 +1073,11 @@ __CreateMapping(
10731073
&(struct MemorySpaceMapOptions) {
10741074
.SHMTag = shmBuffer->ID,
10751075
.Pages = &shmBuffer->Pages[pageIndex],
1076-
.Length = length,
1076+
// Ensure that the length we are requesting pages for actually cover
1077+
// the asked mapping range. If we are requesting a mapping from 0xFFF0
1078+
// and 32 bytes, we will do a page-crossing, and actually we are requesting
1079+
// the entire first page.
1080+
.Length = (length + (actualOffset % pageSize)),
10771081
.Mask = shmBuffer->PageMask,
10781082
.Flags = __RecalculateFlags(shmBuffer->Flags, flags),
10791083
.PlacementFlags = MAPPING_PHYSICAL_FIXED | MAPPING_VIRTUAL_PROCESS
@@ -1137,6 +1141,7 @@ SHMMap(
11371141
if (oserr != OS_EOK) {
11381142
return oserr;
11391143
}
1144+
TRACE("SHMMap: mapping: 0x%p\n", mapping);
11401145

11411146
// Increase the mapping with the built-in offset
11421147
// if this was an exported buffer

kernel/memory/ms_shm_test.c

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ void TestSHMConform_IsConformed(void** state)
851851
// needs to contain the expected setup for the virtual region
852852
g_testContext.MemorySpaceMap.Calls[0].ExpectedSHMTag = 1; // expect 1
853853
g_testContext.MemorySpaceMap.Calls[0].CheckSHMTag = true;
854-
g_testContext.MemorySpaceMap.Calls[0].ExpectedLength = 0x8400;
854+
g_testContext.MemorySpaceMap.Calls[0].ExpectedLength = (0x8400 + 0x856);
855855
g_testContext.MemorySpaceMap.Calls[0].CheckLength = true;
856856
g_testContext.MemorySpaceMap.Calls[0].ExpectedFlags = MAPPING_PERSISTENT | MAPPING_USERSPACE | MAPPING_READONLY;
857857
g_testContext.MemorySpaceMap.Calls[0].CheckFlags = true;
@@ -1678,6 +1678,112 @@ void TestSHMMap_Simple(void** state)
16781678
TeardownTest(state);
16791679
}
16801680

1681+
static void __CreateExportedSHM(SHMHandle_t* shm, const void* buffer, size_t size)
1682+
{
1683+
int pageCount;
1684+
paddr_t* pages;
1685+
oserr_t oserr;
1686+
paddr_t startAddress = 0x1000000;
1687+
1688+
// Create page array
1689+
pageCount = (int)((size + (GetMemorySpacePageSize() - 1)) / GetMemorySpacePageSize());
1690+
pages = test_malloc(pageCount * sizeof(paddr_t));
1691+
assert_non_null(pages);
1692+
1693+
for (int i = 0; i < pageCount; i++) {
1694+
pages[i] = startAddress + (i * GetMemorySpacePageSize());
1695+
}
1696+
1697+
// The following function calls are expected during normal
1698+
// creation:
1699+
1700+
// 1. CreateHandle, nothing really we care enough to check here except
1701+
// that it gets invoked as expected. The default returned value is 1
1702+
1703+
// 2. GetMemorySpaceMapping
1704+
g_testContext.GetMemorySpaceMapping.ExpectedAddress = (vaddr_t)buffer;
1705+
g_testContext.GetMemorySpaceMapping.CheckAddress = true;
1706+
g_testContext.GetMemorySpaceMapping.ExpectedPageCount = pageCount;
1707+
g_testContext.GetMemorySpaceMapping.CheckPageCount = true;
1708+
g_testContext.GetMemorySpaceMapping.PageValues = pages;
1709+
g_testContext.GetMemorySpaceMapping.PageValuesProvided = true;
1710+
g_testContext.GetMemorySpaceMapping.ReturnValue = OS_EOK;
1711+
1712+
oserr = SHMExport(
1713+
(void*)buffer,
1714+
size,
1715+
0,
1716+
0,
1717+
shm
1718+
);
1719+
1720+
// free resources before asserting
1721+
test_free(pages);
1722+
assert_int_equal(oserr, OS_EOK);
1723+
}
1724+
1725+
void TestSHMMap_SimpleExported(void** state)
1726+
{
1727+
oserr_t oserr;
1728+
SHMHandle_t shm;
1729+
void* buffer;
1730+
int sgCount;
1731+
SHMSG_t* sg;
1732+
1733+
// Allocate a new buffer, with wierd values
1734+
buffer = (void*)0x109586;
1735+
1736+
// Create a normal buffer we can use. It must not be comitted. The SHM
1737+
// is already filled, which we don't want as we are trying to make a separate
1738+
// mapping that is not the original.
1739+
__CreateExportedSHM(&shm, buffer, 0xC888);
1740+
1741+
// Ensure new mapping
1742+
shm.Buffer = NULL;
1743+
1744+
// 1. LookupHandleOfType
1745+
g_testContext.LookupHandleOfType.ReturnValue = g_testContext.CreateHandle.Calls[0].CreatedResource;
1746+
1747+
// 2. MemorySpaceMap, this is the most interesting call to check, as that
1748+
// needs to contain the expected setup for the virtual region
1749+
g_testContext.MemorySpaceMap.Calls[0].ExpectedSHMTag = 1; // expect 1
1750+
g_testContext.MemorySpaceMap.Calls[0].CheckSHMTag = true;
1751+
g_testContext.MemorySpaceMap.Calls[0].ExpectedLength = (0xC888 + 0x586);
1752+
g_testContext.MemorySpaceMap.Calls[0].CheckLength = true;
1753+
g_testContext.MemorySpaceMap.Calls[0].ExpectedFlags = MAPPING_PERSISTENT | MAPPING_USERSPACE;
1754+
g_testContext.MemorySpaceMap.Calls[0].CheckFlags = true;
1755+
g_testContext.MemorySpaceMap.Calls[0].ExpectedPlacement = MAPPING_VIRTUAL_PROCESS | MAPPING_PHYSICAL_FIXED;
1756+
g_testContext.MemorySpaceMap.Calls[0].CheckPlacement = true;
1757+
g_testContext.MemorySpaceMap.Calls[0].ReturnedMapping = 0x20000;
1758+
g_testContext.MemorySpaceMap.Calls[0].ReturnedMappingProvided = true;
1759+
g_testContext.MemorySpaceMap.Calls[0].ReturnValue = OS_EOK;
1760+
oserr = SHMMap(
1761+
&shm,
1762+
0,
1763+
shm.Capacity,
1764+
SHM_ACCESS_READ | SHM_ACCESS_WRITE
1765+
);
1766+
assert_int_equal(oserr, OS_EOK);
1767+
assert_ptr_equal(shm.Buffer, (0x20000 + 0x586));
1768+
assert_int_equal(shm.Length, 0xC888);
1769+
1770+
// Ensure that the SG entry shows up correctly
1771+
oserr = SHMBuildSG(shm.ID, &sgCount, NULL);
1772+
assert_int_equal(oserr, OS_EOK);
1773+
assert_int_equal(sgCount, 1);
1774+
1775+
sg = test_malloc(sgCount * sizeof(SHMSG_t));
1776+
assert_non_null(sg);
1777+
1778+
oserr = SHMBuildSG(shm.ID, &sgCount, sg);
1779+
assert_int_equal(oserr, OS_EOK);
1780+
assert_int_equal(sg[0].Address, (0x1000000 + 0x586));
1781+
assert_int_equal(sg[0].Length, 0xCA7A);
1782+
1783+
test_free(sg);
1784+
TeardownTest(state);
1785+
}
1786+
16811787
void TestSHMMap_CanCommit(void** state)
16821788
{
16831789
oserr_t oserr;
@@ -1741,7 +1847,7 @@ void TestSHMMap_CanRemap(void** state)
17411847
// 2. MemorySpaceMap, expect a new mapping of 0x3000 when we map from page 2-4
17421848
g_testContext.MemorySpaceMap.Calls[1].ExpectedSHMTag = 1; // expect 1
17431849
g_testContext.MemorySpaceMap.Calls[1].CheckSHMTag = true;
1744-
g_testContext.MemorySpaceMap.Calls[1].ExpectedLength = 0x2890;
1850+
g_testContext.MemorySpaceMap.Calls[1].ExpectedLength = 0x3000;
17451851
g_testContext.MemorySpaceMap.Calls[1].CheckLength = true;
17461852
g_testContext.MemorySpaceMap.Calls[1].ExpectedFlags = MAPPING_PERSISTENT | MAPPING_USERSPACE;
17471853
g_testContext.MemorySpaceMap.Calls[1].CheckFlags = true;
@@ -1797,6 +1903,7 @@ int main(void)
17971903
cmocka_unit_test_setup(TestSHMAttach_PrivateFailed, SetupTest),
17981904
cmocka_unit_test_setup(TestSHMAttach_InvalidID, SetupTest),
17991905
cmocka_unit_test_setup(TestSHMMap_Simple, SetupTest),
1906+
cmocka_unit_test_setup(TestSHMMap_SimpleExported, SetupTest),
18001907
cmocka_unit_test_setup(TestSHMMap_CanCommit, SetupTest),
18011908
cmocka_unit_test_setup(TestSHMMap_CanRemap, SetupTest),
18021909
};

kernel/sync/mutex.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ __SlowLock(
102102
irqstate_t intStatus;
103103
uuid_t owner;
104104

105+
// TODO: Detect mutex locking during IRQs
106+
105107
// Disable interrupts and try to acquire the lock or wait for the lock
106108
// to unlock if it's held on another CPU - however we only wait for a brief period
107109
intStatus = InterruptDisable();

librt/libc/io/open.c

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
#define __TRACE
18+
//#define __TRACE
1919
#define __need_minmax
2020
#include <ddk/utils.h>
2121
#include <errno.h>
@@ -152,7 +152,7 @@ __transfer(
152152
_In_ size_t chunkSize,
153153
_In_ size_t offset,
154154
_In_ size_t length,
155-
_Out_ size_t* bytesTransferreOut)
155+
_Out_ size_t* bytesTransferedOut)
156156
{
157157
size_t bytesLeft = length;
158158
oserr_t oserr;
@@ -182,7 +182,7 @@ __transfer(
182182
offset += bytesTransferred;
183183
}
184184

185-
*bytesTransferreOut = length - bytesLeft;
185+
*bytesTransferedOut = length - bytesLeft;
186186
return oserr;
187187
}
188188

@@ -194,32 +194,14 @@ __read_large(
194194
_Out_ size_t* bytesReadOut)
195195
{
196196
OSHandle_t shm;
197-
void* adjustedPointer = (void*)buffer;
198-
size_t adjustedLength = length;
199-
size_t pageSize = MemoryPageSize();
200197
oserr_t oserr;
201198
TRACE("__read_large(buffer=0x%" PRIxIN ", length=%" PRIuIN ")", buffer, length);
202199

203-
// enforce page alignment on the buffer
204-
if ((uintptr_t)buffer & (pageSize - 1)) {
205-
size_t bytesToAlign = pageSize - ((uintptr_t)buffer & (pageSize - 1));
206-
TRACE("__read_large: aligning buffer=0x%" PRIxIN ", align=0x%" PRIxIN,
207-
buffer, bytesToAlign);
208-
oserr = __file_read(handle, buffer, bytesToAlign, bytesReadOut);
209-
if (oserr != OS_EOK || *bytesReadOut == 0) {
210-
return oserr;
211-
}
212-
adjustedPointer = (void*)((uintptr_t)buffer + bytesToAlign);
213-
adjustedLength -= bytesToAlign;
214-
}
215-
216-
TRACE("__read_large: exporting buffer=0x%" PRIxIN ", length=0x%" PRIxIN,
217-
adjustedPointer, adjustedLength);
218200
oserr = SHMExport(
219-
adjustedPointer,
201+
buffer,
220202
&(SHM_t) {
221203
.Access = SHM_ACCESS_READ | SHM_ACCESS_WRITE,
222-
.Size = adjustedLength
204+
.Size = length
223205
},
224206
&shm
225207
);
@@ -232,15 +214,11 @@ __read_large(
232214
handle->OSHandle.ID,
233215
shm.ID,
234216
false,
235-
adjustedLength,
217+
length,
236218
0,
237-
adjustedLength,
219+
length,
238220
bytesReadOut
239221
);
240-
if (*bytesReadOut == adjustedLength) {
241-
*bytesReadOut = length;
242-
}
243-
244222
OSHandleDestroy(&shm);
245223
return oserr;
246224
}
@@ -290,32 +268,13 @@ __write_large(
290268
_Out_ size_t* bytesWrittenOut)
291269
{
292270
OSHandle_t shm;
293-
void* adjustedPointer = (void*)buffer;
294-
size_t adjustedLength = length;
295-
size_t pageSize = MemoryPageSize();
296271
oserr_t oserr;
297272
TRACE("__write_large(buffer=0x%" PRIxIN ", length=%" PRIuIN ")", buffer, length);
298-
299-
// enforce page alignment on the buffer
300-
if ((uintptr_t)buffer & (pageSize - 1)) {
301-
size_t bytesToAlign = pageSize - ((uintptr_t)buffer & (pageSize - 1));
302-
TRACE("__write_large: aligning buffer=0x%" PRIxIN ", align=0x%" PRIxIN,
303-
buffer, bytesToAlign);
304-
oserr = __file_write(handle, buffer, bytesToAlign, bytesWrittenOut);
305-
if (oserr != OS_EOK|| *bytesWrittenOut == 0) {
306-
return oserr;
307-
}
308-
adjustedPointer = (void*)((uintptr_t)buffer + bytesToAlign);
309-
adjustedLength -= bytesToAlign;
310-
}
311-
312-
TRACE("__write_large: exporting buffer=0x%" PRIxIN ", length=0x%" PRIxIN,
313-
adjustedPointer, adjustedLength);
314273
oserr = SHMExport(
315-
adjustedPointer,
274+
(void*)buffer,
316275
&(SHM_t) {
317276
.Access = SHM_ACCESS_READ | SHM_ACCESS_WRITE,
318-
.Size = adjustedLength
277+
.Size = length
319278
},
320279
&shm
321280
);
@@ -326,15 +285,12 @@ __write_large(
326285
oserr = __transfer(
327286
handle->OSHandle.ID, shm.ID,
328287
true,
329-
adjustedLength,
288+
length,
330289
0,
331-
adjustedLength,
290+
length,
332291
bytesWrittenOut
333292
);
334293
OSHandleDestroy(&shm);
335-
if (*bytesWrittenOut == adjustedLength) {
336-
*bytesWrittenOut = length;
337-
}
338294
return oserr;
339295
}
340296

librt/libc/stdio/fread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18+
//#define __TRACE
1819
#define __need_minmax
19-
#define __TRACE
2020
#include <ddk/utils.h>
2121
#include <errno.h>
2222
#include <internal/_file.h>

librt/libc/stdio/fwrite.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18+
//#define __TRACE
1819
#define __need_minmax
19-
#define __TRACE
20-
2120
#include <ddk/utils.h>
2221
#include <errno.h>
2322
#include <io.h>

librt/libddk/include/ddk/barrier.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
///////////////////////////////////////////////////////////////////////////////
7979
//// Clang
8080
///////////////////////////////////////////////////////////////////////////////
81-
#elif defined(__clang__)
81+
#elif defined(__clang__) || defined(__GNUC__)
8282
#define sw_mb() __asm__ __volatile__ ( "" ::: "memory" )
8383
#define sw_rmb() __asm__ __volatile__ ( "" ::: "memory" )
8484
#define sw_wmb() __asm__ __volatile__ ( "" ::: "memory" )

0 commit comments

Comments
 (0)