nuta on main
x64: Fix an mis-use of XSAVE/XR… (compare)
nuta on rust
nuta on virtio-gpu
nuta on v0.9.0
nuta on main
v0.9.0 (compare)
nuta on main
Add virtio-gpu driver (compare)
nuta on main
virtio: Implement get_next_inde… virtio: Support probing a virti… virtio: Some fixes to get data … (compare)
nuta on virtio-gpu
wip (compare)
nuta on virtio-gpu
Update Update Update and 2 more (compare)
nuta on virtio-gpu
Update Update (compare)
nuta on virtio-gpu
Update Update Update and 5 more (compare)
nuta on pie
Update (compare)
nuta on master
nuta on main
shm
in linux.Also, I believe shm.c
to be a part of resea/include/
or will it be in the kernel/
as well ?
@nuta Won't the test for nuta/resea#28 be similar to usage of
shm
in linux.
I think so. Specifically, we need at least two tasks (apps/test
and a new app like app/shm_test
). app/test
creates a shared memory and tell it app/shm_test
. It maps the shm and writes something to the shm. Lastly, apps/test
checks if the written data is visible.
Also, I believe
shm.c
to be a part ofresea/include/
or will it be in thekernel/
as well ?
Do you mean API wrappers like libs/resea/include/async.h
? If so, I think it should be resea/include/experimental/shm.h
since its not yet matured feature.
@malbx Your design looks good to me! Could you create a PR? Let's improve it incrementally.
Also, do you have any thoughts on how you would like to handle the seed?
Towards a cryptographic-secure RNG, we might need to add kernel support and a system call to get the seed from the hardware. I'm not familiar with random number generators but AFAIK Linux extracts randomness from interrupt timings and RDRAND instruction on x64.
virtio-blk
and Userspace debugging using LLDB
on the board. Which one do you think is more suitable given the short timeframe? Does the LLDB one involve that much work? Please let me know your thoughts.
@nuta So I started some work on the virtio-blk
driver and went through the spec and some existing implementations (1, 2).
I noticed how they're sending three different buffers (one for header, one for data and one for device writeable status byte) and chaining them using the next
field. resea's virtio_modern
implementation doesn't have that but does mention descriptor chaining
in the code. So can you please explain how that would work in resea?
I think I should be able to make it work like those existing ones using the legacy interface but I'm confused regarding how chaining works in the modern implementation.
@PrayagS I think implementing virtio-blk driver (for legacy virtio device) is more realistic.
You may already know, Resea's virtio_modern implementation uses Packed Virtqueue. See 2.7.6 Next Flag: Descriptor Chaining in the spec (the specification describes both legacy and modern devices in the single page and it makes a bit confusing...).
I haven't tried yet but according to the QEMU's implemenetation (in virtqueue_packed_read_next_desc()
), we don't use next
field in the packed virtqueue. Instead, we need to use continuous descriptors as a chain and set VIRTIO_DESC_F_NEXT
to the descriptor flags (except the last one).
The current virtio-net driver does not use that simply because it's not needed. Thus, you may also need to improve also the Resea's virtio_modern to handle the descriptor chaining.
next
field and just set the flags accordingly. Please let me know if I wrongly interpreted this. I'll still implement it for the legacy device first and then proceed with the modern implementation.
since we're using packed virtqueues, we don't need to set the next field and just set the flags accordingly
i'm not 100% sure but I think so.
I'll still implement it for the legacy device first and then proceed with the modern implementation.
Ah I got it wrong. It looks that Resea's virtio library abstracts modern/legacy interfaces so you won't have to care the differences.
Relevant section from the paper -
We use the following encoding for each shadow byte:
0 means that all 8 bytes of the corresponding application
memory region are addressable; k (1 ≤ k ≤ 7) means that
the first k bytes are addressible; any negative value indi-
cates that the entire 8-byte word is unaddressable. We
use different negative values to distinguish between dif-
ferent kinds of unaddressable memory (heap redzones,
stack redzones, global redzones, freed memory).
vq->num_descs
number of buffers of both the same size and r/w access (either all are device-writeable for reading or all are device-readable for transmission).virtio-blk
, as I had mentioned before, the buffer containing the header needs to be device-readable. The payload buffer's r/w access depends on the operation. And the status byte needs to be device-writeable.VIRTIO_DESC_F_NEXT
flag. Most of what I did is according to the examples given in the spec (2.7.21.3 and 2.7.22).virtq_allocate_buffers()
to allocate buffers of the same size regardless of their type.id
part since all the elements of a block request are referred to as elements of a buffer whose ID is stored in the last descriptor of the chain.
hw/virtio/virtio.c
).
@nuta I was thinking I can take up one more task in parallel with KASAN, now that my exams are over and I have some time (and curiosity xD). Are we considering a slab allocation scheme in malloc?
A slab allocator sounds good idea :)
Hi @nuta, our 6 weeks are about to get over. We have our project presentation scheduled this Sunday evening. where we have to explain what we did and show our work (Fingers crossed haha :D). But that is just for our University and we'd love to continue working on the features we're implementing. Meantime, we'd be really grateful if you can share what you feel about our work, which we can use as a testimony in the concluding part of our presentation.
It's the first time we worked on an open-source at this scale and you've been a true guide to us in our journey! Thanks a ton :heart:
@PrayagS Good point. Currently, I'm working on the virtio-gpu driver and plan to improve the virtio library in couple of days. In the improvement, I'll try addressing the issue you described. FWIW, you can investigate why your virtio driver doesn't work by inserting some printf functions into QEMU (
hw/virtio/virtio.c
).
I've pushed improvements on virtio library to allow constructing a descriptor chain. Can you try it out?
@yashrajkakkad Sure. Can you share your git branch for KASAN?
@yashrajkakkad I tried your code and it failed with general protection fault.
[kernel] WARN: Exception #13
[kernel] RIP = 0000000001005cc5 CS = 000000000000002b RFL = 0000000000000246
[kernel] SS = 0000000000000023 RSP = 000000000300ad70 RBP = 000000000300adb0
[kernel] RAX = 0a110ced0a110ced RBX = 0000000000000004 RCX = 0000000000000001
[kernel] RDX = 0000000004124120 RSI = 00000000000000aa RDI = f8f8f8f8f8f8f910
[kernel] R8 = 0000000000000003 R9 = 0000000000000000 R10 = 000000000300abd0
[kernel] R11 = 0000000000000246 R12 = f8f8f8f8f8f8f910 R13 = 0000000000000010
[kernel] R14 = 0000000000000020 R15 = f8f8f8f8f8f8f8f8 ERR = 0000000000000000
[vm] WARN: test: exception occurred, killing the task...
[kernel] destroying test...
QEMU 4.2.1 monitor - type 'help' for more information
(qemu) xp /i 0x1005cc5
0x01005cc5: 00 00 addb %al, (%rax)
I think this is caused by accessing a non-canonical address in RAX by ADD instruction.
I'm not sure but I guess some part of the memory (e.g. return address in the stack) is accidentally overwritten because RIP = 0x1005cc5 seems to be incorrect:
$ objdump -d build/vm.debug.elf|egrep '1005cc[0-9a-z]'
1005930: 0f 85 8d 03 00 00 jne 1005cc3 <vaddr2paddr+0x3e3>
1005cc3: 48 bf c0 19 00 03 00 movabs $0x30019c0,%rdi
1005cca: 00 00 00 <-- instruction at 1005cc5 does not exist
1005ccd: 48 89 de mov %rbx,%rsi
Sadly, fixing your bug might take a time...
__shadow
is too small and shadow_free
accidentally destroyed other memory area. Thus it reproduces even if KASAN is disabled. Try the following patch: diff --git a/libs/resea/malloc.c b/libs/resea/malloc.c
index e8040b25..5f78190c 100644
--- a/libs/resea/malloc.c
+++ b/libs/resea/malloc.c
@@ -345,6 +345,14 @@ void shadow_free(struct malloc_chunk *chunk)
reladdr = ptr_cur - (paddr_t)__heap;
reladdr >>= 3;
DBG("%u", reladdr);
+
+ size_t len = chunk->capacity + MALLOC_REDZONE_LEN;
+ if ((vaddr_t) &__shadow[reladdr] + len >= (vaddr_t) __shadow_end) {
+ WARN_DBG("__shadow is too small: addr=%p, len=%d, reladdr=%p",
+ &__shadow[reladdr], len, reladdr);
+ return;
+ }
+
for(size_t i = 0; i < (chunk->capacity + MALLOC_REDZONE_LEN); i++)
{
__shadow[reladdr++] = SHADOW_FREED;