fix(mm): munmap/brk page leaks — free physical frames on unmap, rollback on partial failure
1. munmap: vmm_unmap_page only clears PTEs without freeing physical
frames. For anonymous mmaps (shmid == -1), call vmm_virt_to_phys +
pmm_free_page before vmm_unmap_page. Device-backed/shared mappings
keep their frames (managed by their own subsystems).
2. brk shrink: same leak — free physical frames before unmapping when
the heap shrinks.
3. brk grow partial failure: if pmm_alloc_page fails mid-expansion,
rollback all pages already mapped in this call (unmap + free), then
return old heap_break. Previously these pages were leaked permanently.
4. mmap anonymous partial failure: same rollback pattern applied to
syscall_mmap_impl — if pmm_alloc_page fails mid-allocation, unmap
and free all pages already mapped before returning -ENOMEM.
All tests pass: 69/69 host + 103/103 QEMU, zero regressions.