Skip to content

Commit f890857

Browse files
committed
address review
1 parent b1f253e commit f890857

6 files changed

Lines changed: 111 additions & 86 deletions

File tree

etc/syscalls_linux_aarch64.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158
| 0x9b (155) | getpgid | (pid_t pid) | __arm64_sys_getpgid | true |
159159
| 0x9c (156) | getsid | (pid_t pid) | __arm64_sys_getsid | true |
160160
| 0x9d (157) | setsid | () | __arm64_sys_setsid | true |
161-
| 0x9e (158) | getgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_getgroups | false |
161+
| 0x9e (158) | getgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_getgroups | stub |
162162
| 0x9f (159) | setgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_setgroups | false |
163163
| 0xa0 (160) | newuname | (struct new_utsname *name) | __arm64_sys_newuname | true |
164164
| 0xa1 (161) | sethostname | (char *name, int len) | __arm64_sys_sethostname | true |

libkernel/src/arch/arm64/memory/pg_walk.rs

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22
33
use super::{
44
pg_descriptors::L3Descriptor,
5-
pg_tables::{L0Table, L3Table},
5+
pg_tables::{L0Table, L1Table, L3Table},
66
};
77
use crate::{
88
error::{MapError, Result},
99
memory::{
1010
PAGE_SIZE,
11-
address::{TPA, VA},
11+
address::{PA, TPA, VA},
1212
paging::{
13-
NullTlbInvalidator, PageTableEntry, PageTableMapper, PgTable, PgTableArray,
14-
walk::{RecursiveWalker, WalkContext},
13+
NullTlbInvalidator, PaMapper, PageTableEntry, PageTableMapper, PgTable, PgTableArray,
14+
TableMapper,
15+
permissions::PtePermissions,
16+
walk::{RecursiveWalker, Translator, WalkContext},
1517
},
16-
region::VirtMemoryRegion,
18+
region::{PhysMemoryRegion, VirtMemoryRegion},
1719
},
1820
};
1921

@@ -111,6 +113,71 @@ pub fn get_pte<PM: PageTableMapper>(
111113
Ok(descriptor)
112114
}
113115

116+
impl Translator for L0Table {
117+
fn translate<PM: PageTableMapper>(
118+
table_pa: TPA<PgTableArray<Self>>,
119+
va: VA,
120+
ctx: &mut WalkContext<PM>,
121+
) -> Result<Option<(PA, usize, PtePermissions)>> {
122+
let desc = unsafe {
123+
ctx.mapper
124+
.with_page_table(table_pa, |pgtable| Self::from_ptr(pgtable).get_desc(va))?
125+
};
126+
127+
match desc.next_table_address() {
128+
Some(next_pa) => L1Table::translate(next_pa, va, ctx),
129+
None if desc.is_valid() => Err(MapError::InvalidDescriptor.into()),
130+
None => Ok(None),
131+
}
132+
}
133+
}
134+
135+
impl Translator for L3Table {
136+
fn translate<PM: PageTableMapper>(
137+
table_pa: TPA<PgTableArray<Self>>,
138+
va: VA,
139+
ctx: &mut WalkContext<PM>,
140+
) -> Result<Option<(PA, usize, PtePermissions)>> {
141+
let desc = unsafe {
142+
ctx.mapper
143+
.with_page_table(table_pa, |pgtable| Self::from_ptr(pgtable).get_desc(va))?
144+
};
145+
146+
match desc.mapped_address() {
147+
Some(pa) => Ok(Some((
148+
pa,
149+
1 << Self::Descriptor::MAP_SHIFT,
150+
desc.permissions().unwrap(),
151+
))),
152+
None if desc.is_valid() => Err(MapError::InvalidDescriptor.into()),
153+
None => Ok(None),
154+
}
155+
}
156+
}
157+
158+
/// Translates the VA into a physical region plus an offset and permissions.
159+
pub fn translate<PM: PageTableMapper>(
160+
l0_table: TPA<PgTableArray<L0Table>>,
161+
va: VA,
162+
mapper: &mut PM,
163+
) -> Result<Option<(PhysMemoryRegion, usize, PtePermissions)>> {
164+
let mut walk_ctx = WalkContext {
165+
mapper,
166+
// Safe to not invalidate the TLB, as we are not modifying any PTEs.
167+
invalidator: &NullTlbInvalidator {},
168+
};
169+
170+
if let Some((pa, blk_sz, perms)) = L0Table::translate(l0_table, va, &mut walk_ctx)? {
171+
debug_assert!(blk_sz.is_power_of_two());
172+
173+
let offset = va.value() & (blk_sz - 1);
174+
175+
Ok(Some((PhysMemoryRegion::new(pa, blk_sz), offset, perms)))
176+
} else {
177+
Ok(None)
178+
}
179+
}
180+
114181
#[cfg(test)]
115182
mod tests {
116183
use super::*;

src/arch/arm64/memory/address_space.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use libkernel::{
1414
pg_descriptors::{L3Descriptor, MemoryType},
1515
pg_tables::{L0Table, MapAttributes, MappingContext, map_range},
1616
pg_tear_down::tear_down_address_space,
17-
pg_walk::{get_pte, walk_and_modify_region},
17+
pg_walk::{translate as translate_va, walk_and_modify_region},
1818
},
1919
error::{KernelError, MapError, Result},
2020
memory::{
@@ -137,16 +137,15 @@ impl UserAddressSpace for Arm64ProcessAddressSpace {
137137
}
138138

139139
fn translate(&self, va: VA) -> Option<PageInfo> {
140-
let pte = get_pte(
141-
self.l0_table,
142-
va.page_aligned(),
143-
&mut PageOffsetPgTableMapper {},
144-
)
145-
.unwrap()?;
140+
let (region, offset, perms) =
141+
translate_va(self.l0_table, va, &mut PageOffsetPgTableMapper {})
142+
.ok()
143+
.flatten()?;
144+
let pa = region.start_address().add_bytes(offset);
146145

147146
Some(PageInfo {
148-
pfn: pte.mapped_address()?.to_pfn(),
149-
perms: pte.permissions()?,
147+
pfn: pa.to_pfn(),
148+
perms,
150149
})
151150
}
152151

src/arch/arm64/memory/mmu.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ use libkernel::{
44
arch::arm64::memory::{
55
pg_descriptors::MemoryType,
66
pg_tables::{L0Table, MapAttributes, MappingContext, map_range},
7-
pg_walk::get_pte,
7+
pg_walk::translate as translate_va,
88
},
99
error::Result,
1010
memory::{
1111
address::{PA, TPA, VA},
12-
paging::{PaMapper, PgTableArray, permissions::PtePermissions},
12+
paging::{PgTableArray, permissions::PtePermissions},
1313
proc_vm::address_space::KernAddressSpace,
1414
region::{PhysMemoryRegion, VirtMemoryRegion},
1515
},
@@ -39,16 +39,11 @@ impl Arm64KernelAddressSpace {
3939
map_range(self.kernel_l0, map_attrs, &mut ctx)
4040
}
4141

42-
pub fn translate(&self, va: VA) -> Option<PA> {
43-
let pg_offset = va.page_offset();
44-
45-
let pte = get_pte(self.kernel_l0, va, &mut PageOffsetPgTableMapper {})
42+
pub fn translate(&self, va: VA) -> Option<(PhysMemoryRegion, usize)> {
43+
translate_va(self.kernel_l0, va, &mut PageOffsetPgTableMapper {})
4644
.ok()
47-
.flatten()?;
48-
49-
let pa = pte.mapped_address()?;
50-
51-
Some(pa.add_bytes(pg_offset))
45+
.flatten()
46+
.map(|(region, offset, _)| (region, offset))
5247
}
5348

5449
pub fn table_pa(&self) -> PA {

src/drivers/virtio_hal.rs

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,36 @@ impl VirtioHal {
2626
rounded.ilog2() as u8
2727
}
2828

29-
fn translated_phys_addr(vaddr: VA) -> Option<PhysAddr> {
30-
ArchImpl::kern_address_space()
31-
.lock_save_irq()
32-
.translate(vaddr)
33-
.map(|pa| pa.value() as PhysAddr)
34-
}
35-
3629
fn translate_buffer(vaddr: VA, len: usize) -> Option<PhysAddr> {
3730
debug_assert!(len > 0);
3831

39-
let first_page_va = vaddr.page_aligned();
40-
let last_byte_va = vaddr.add_bytes(len - 1);
41-
let last_page_va = last_byte_va.page_aligned();
42-
43-
let first_page_pa = Self::translated_phys_addr(first_page_va)?;
44-
let mut page_va = first_page_va;
45-
let mut expected_page_pa = first_page_pa;
46-
47-
loop {
48-
let page_pa = Self::translated_phys_addr(page_va)?;
49-
if page_pa != expected_page_pa {
50-
return None;
32+
let addr_space = ArchImpl::kern_address_space().lock_save_irq();
33+
let mut next_va = vaddr;
34+
let mut remaining = len;
35+
let mut start_pa = None;
36+
let mut expected_next_pa = None;
37+
38+
while remaining > 0 {
39+
let (phys_region, offset) = addr_space.translate(next_va)?;
40+
let translated_pa = phys_region.start_address().add_bytes(offset).value() as PhysAddr;
41+
42+
if let Some(expected_pa) = expected_next_pa {
43+
if translated_pa != expected_pa {
44+
return None;
45+
}
46+
} else {
47+
start_pa = Some(translated_pa);
5148
}
5249

53-
if page_va == last_page_va {
54-
break;
55-
}
50+
let mapped_len = phys_region.size() - offset;
51+
let covered_len = mapped_len.min(remaining);
5652

57-
page_va = page_va.add_pages(1);
58-
expected_page_pa += PAGE_SIZE as PhysAddr;
53+
next_va = next_va.add_bytes(covered_len);
54+
remaining -= covered_len;
55+
expected_next_pa = Some(translated_pa + covered_len as PhysAddr);
5956
}
6057

61-
Some(first_page_pa + vaddr.page_offset() as PhysAddr)
58+
start_pa
6259
}
6360

6461
fn bounce_copy_in(paddr: PhysAddr, src: &[u8]) {
@@ -98,12 +95,6 @@ impl VirtioHal {
9895
.lock_save_irq()
9996
.push(BouncedShare { paddr, pages });
10097

101-
// trace!(
102-
// "virtio share: bounced {:p} len={} direction={direction:?} to paddr={paddr:#x}",
103-
// buffer.as_ptr(),
104-
// buffer.len(),
105-
// );
106-
10798
paddr
10899
}
109100
}
@@ -130,13 +121,10 @@ unsafe impl Hal for VirtioHal {
130121
core::ptr::write_bytes(vaddr.as_ptr(), 0, pages * PAGE_SIZE);
131122
}
132123

133-
// trace!("alloc DMA: paddr={paddr:#x}, pages={pages}, order={order}");
134124
(paddr, vaddr)
135125
}
136126

137127
unsafe fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull<u8>, pages: usize) -> i32 {
138-
// trace!("dealloc DMA: paddr={paddr:#x}, pages={pages}");
139-
140128
let order = Self::pages_to_order(pages);
141129
let region = PhysMemoryRegion::new(
142130
PA::from_value(paddr as usize),

src/fs/syscalls/pivot_root.rs

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use crate::{
2-
fs::VFS, memory::uaccess::cstr::UserCStr, process::TASK_LIST, sched::syscall_ctx::ProcessCtx,
3-
};
1+
use crate::{fs::VFS, memory::uaccess::cstr::UserCStr, sched::syscall_ctx::ProcessCtx};
42
use alloc::sync::Arc;
53
use core::ffi::c_char;
64
use libkernel::{
@@ -110,29 +108,7 @@ pub async fn sys_pivot_root(
110108
return Err(KernelError::InUse);
111109
}
112110

113-
let (old_root_inode, new_root_inode) =
114-
VFS.pivot_root(new_root_attachment, put_old_attachment)?;
115-
116-
let tasks: alloc::vec::Vec<_> = TASK_LIST
117-
.lock_save_irq()
118-
.values()
119-
.filter_map(|work| work.upgrade())
120-
.collect();
121-
122-
for work in tasks {
123-
let task = work.task.t_shared.clone();
124-
125-
let mut root = task.root.lock_save_irq();
126-
if root.0.id() == old_root_inode.id() {
127-
*root = (new_root_inode.clone(), "/".into());
128-
}
129-
drop(root);
130-
131-
let mut cwd = task.cwd.lock_save_irq();
132-
if cwd.0.id() == old_root_inode.id() {
133-
*cwd = (new_root_inode.clone(), "/".into());
134-
}
135-
}
111+
let _ = VFS.pivot_root(new_root_attachment, put_old_attachment)?;
136112

137113
Ok(0)
138114
}

0 commit comments

Comments
 (0)