fix: bugs

This commit is contained in:
Faynot
2026-07-06 00:25:49 +03:00
parent 1b38c7f445
commit c092a81331
23 changed files with 2502 additions and 123 deletions

85
kernel/docs/events.md Normal file
View File

@@ -0,0 +1,85 @@
# Очередь отзыва (RevocationQueue)
**Файл**: `src/events.rs`
Lock-free MPSC (Multi-Producer Single-Consumer) очередь для уведомления VMM об отзыве capability.
---
## RevocationQueue
```rust
pub struct RevocationQueue {
buffer: [AtomicU64; QUEUE_SIZE], // 1024 слота
_pad0: [u8; 64], // cache-line padding
head: AtomicUsize, // индекс потребителя (VMM)
_pad1: [u8; 64], // ещё padding
tail: AtomicUsize, // индекс производителя (CNode)
}
```
Cache-line padding (64 байта) предотвращает **false sharing** между head и tail на разных кэш-линиях.
### Константы
- `QUEUE_SIZE = 1024`
- `QUEUE_MASK = 1023`
### `new() -> Self`
Все слоты = 0, head = 0, tail = 0.
### `push(token_sig: u64) -> Result<(), &'static str>`
1. Читает `tail` (Relaxed)
2. CAS-цикл: пытается захватить следующий слот
3. Если буфер полон (`tail - head == QUEUE_SIZE`): ошибка
4. Записывает `token_sig` в `buffer[tail & QUEUE_MASK]` (Release ordering)
5. Обновляет `tail` (Release)
**Производители**: CNode::revoke() — при каждом отзыве пушит token_sig.
### `pop() -> Option<u64>`
1. Читает `tail` (Acquire) и `head` (Relaxed)
2. Если `head == tail`: буфер пуст, None
3. Читает `buffer[head & QUEUE_MASK]` (Acquire)
4. Обновляет `head` (Release)
5. Возвращает token
**Потребитель**: VMM — `AddressSpace::process_pending_revocations()`.
---
## Глобальный экземпляр
```rust
pub static MMU_REVOCATION_QUEUE: RevocationQueue = RevocationQueue::new();
```
---
## Полный цикл ревокации
```
CNode::revoke(slot_idx)
→ revoke_internal(slot_idx) // рекурсивное уничтожение потомков
→ slot = Empty
→ MMU_REVOCATION_QUEUE.push(token_sig)
... позже, при page fault ...
rust_page_fault_handler()
→ process_deferred_mmu_events()
→ KERNEL_SPACE.lock()
→ process_pending_revocations()
→ while let Some(token) = MMU_REVOCATION_QUEUE.pop()
→ revoke_by_token(token)
→ unmap matching VMAs (кроме PINNED)
→ TLB flush
→ KERNEL_SPACE.lock()
→ handle_fault(fault_addr, write) // обработка исходного fault
```
**Почему такая очерёдность?** Ревокации обрабатываются **до** захвата VMM для page fault, чтобы избежать deadlock'а: и revoke, и handle_fault хотят lock на `KERNEL_SPACE`.