Skip to content

Commit d19cf28

Browse files
authored
Merge pull request #546 from rust-osdev/master
merge master into next
2 parents cd14167 + 284bdca commit d19cf28

File tree

13 files changed

+361
-23
lines changed

13 files changed

+361
-23
lines changed

.github/workflows/build.yml

+5-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
strategy:
4848
fail-fast: false
4949
matrix:
50-
platform: [ubuntu-latest, macos-12, macos-latest, windows-latest]
50+
platform: [ubuntu-latest, macos-latest, windows-latest]
5151

5252
runs-on: ${{ matrix.platform }}
5353
timeout-minutes: 15
@@ -89,9 +89,6 @@ jobs:
8989
runs-on: ${{ matrix.platform }}
9090
timeout-minutes: 15
9191

92-
env:
93-
RUSTFLAGS: -Crelocation-model=static -Dwarnings
94-
9592
steps:
9693
- name: "Checkout Repository"
9794
uses: actions/checkout@v4
@@ -137,9 +134,11 @@ jobs:
137134
run: qemu-system-x86_64 --version
138135

139136
- name: "Run Test Framework"
140-
run: cargo test
137+
run: cargo test --target x86_64-unknown-none
141138
shell: bash
142139
working-directory: "testing"
140+
env:
141+
RUSTFLAGS: -Crelocation-model=static -Dwarnings
143142

144143
check_formatting:
145144
name: "Check Formatting"
@@ -177,7 +176,7 @@ jobs:
177176
run: cargo +stable semver-checks check-release
178177

179178
kani:
180-
runs-on: ubuntu-20.04
179+
runs-on: ubuntu-latest
181180
steps:
182181
- uses: actions/checkout@v4
183182
- uses: Swatinem/rust-cache@v2

.github/workflows/release.yml

+1-5
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,8 @@ jobs:
2121
- name: "Checkout Repository"
2222
uses: actions/checkout@v4
2323

24-
# TODO: Remove when Python 3.11 is the default on the Gihtub Actions image
25-
- name: "Install Python 3.11"
26-
run: sudo apt-get -y install python3.11
27-
2824
- name: "Run release script"
29-
run: "python3.11 scripts/ci-release.py"
25+
run: "python scripts/ci-release.py"
3026
env:
3127
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
3228
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

src/addr.rs

+92-4
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,41 @@ impl fmt::Pointer for VirtAddr {
364364

365365
impl Add<u64> for VirtAddr {
366366
type Output = Self;
367+
368+
#[cfg_attr(not(feature = "step_trait"), allow(rustdoc::broken_intra_doc_links))]
369+
/// Add an offset to a virtual address.
370+
///
371+
/// This function performs normal arithmetic addition and doesn't jump the
372+
/// address gap. If you're looking for a successor operation that jumps the
373+
/// address gap, use [`Step::forward`].
374+
///
375+
/// # Panics
376+
///
377+
/// This function will panic on overflow or if the result is not a
378+
/// canonical address.
367379
#[inline]
368380
fn add(self, rhs: u64) -> Self::Output {
369-
VirtAddr::new(self.0 + rhs)
381+
VirtAddr::try_new(
382+
self.0
383+
.checked_add(rhs)
384+
.expect("attempt to add with overflow"),
385+
)
386+
.expect("attempt to add resulted in non-canonical virtual address")
370387
}
371388
}
372389

373390
impl AddAssign<u64> for VirtAddr {
391+
#[cfg_attr(not(feature = "step_trait"), allow(rustdoc::broken_intra_doc_links))]
392+
/// Add an offset to a virtual address.
393+
///
394+
/// This function performs normal arithmetic addition and doesn't jump the
395+
/// address gap. If you're looking for a successor operation that jumps the
396+
/// address gap, use [`Step::forward`].
397+
///
398+
/// # Panics
399+
///
400+
/// This function will panic on overflow or if the result is not a
401+
/// canonical address.
374402
#[inline]
375403
fn add_assign(&mut self, rhs: u64) {
376404
*self = *self + rhs;
@@ -379,13 +407,41 @@ impl AddAssign<u64> for VirtAddr {
379407

380408
impl Sub<u64> for VirtAddr {
381409
type Output = Self;
410+
411+
#[cfg_attr(not(feature = "step_trait"), allow(rustdoc::broken_intra_doc_links))]
412+
/// Subtract an offset from a virtual address.
413+
///
414+
/// This function performs normal arithmetic subtraction and doesn't jump
415+
/// the address gap. If you're looking for a predecessor operation that
416+
/// jumps the address gap, use [`Step::backward`].
417+
///
418+
/// # Panics
419+
///
420+
/// This function will panic on overflow or if the result is not a
421+
/// canonical address.
382422
#[inline]
383423
fn sub(self, rhs: u64) -> Self::Output {
384-
VirtAddr::new(self.0.checked_sub(rhs).unwrap())
424+
VirtAddr::try_new(
425+
self.0
426+
.checked_sub(rhs)
427+
.expect("attempt to subtract with overflow"),
428+
)
429+
.expect("attempt to subtract resulted in non-canonical virtual address")
385430
}
386431
}
387432

388433
impl SubAssign<u64> for VirtAddr {
434+
#[cfg_attr(not(feature = "step_trait"), allow(rustdoc::broken_intra_doc_links))]
435+
/// Subtract an offset from a virtual address.
436+
///
437+
/// This function performs normal arithmetic subtraction and doesn't jump
438+
/// the address gap. If you're looking for a predecessor operation that
439+
/// jumps the address gap, use [`Step::backward`].
440+
///
441+
/// # Panics
442+
///
443+
/// This function will panic on overflow or if the result is not a
444+
/// canonical address.
389445
#[inline]
390446
fn sub_assign(&mut self, rhs: u64) {
391447
*self = *self - rhs;
@@ -394,9 +450,17 @@ impl SubAssign<u64> for VirtAddr {
394450

395451
impl Sub<VirtAddr> for VirtAddr {
396452
type Output = u64;
453+
454+
/// Returns the difference between two addresses.
455+
///
456+
/// # Panics
457+
///
458+
/// This function will panic on overflow.
397459
#[inline]
398460
fn sub(self, rhs: VirtAddr) -> Self::Output {
399-
self.as_u64().checked_sub(rhs.as_u64()).unwrap()
461+
self.as_u64()
462+
.checked_sub(rhs.as_u64())
463+
.expect("attempt to subtract with overflow")
400464
}
401465
}
402466

@@ -593,7 +657,7 @@ impl Add<u64> for PhysAddr {
593657
type Output = Self;
594658
#[inline]
595659
fn add(self, rhs: u64) -> Self::Output {
596-
PhysAddr::new(self.0 + rhs)
660+
PhysAddr::new(self.0.checked_add(rhs).unwrap())
597661
}
598662
}
599663

@@ -663,6 +727,30 @@ pub const fn align_up(addr: u64, align: u64) -> u64 {
663727
mod tests {
664728
use super::*;
665729

730+
#[test]
731+
#[should_panic]
732+
pub fn add_overflow_virtaddr() {
733+
let _ = VirtAddr::new(0xffff_ffff_ffff_ffff) + 1;
734+
}
735+
736+
#[test]
737+
#[should_panic]
738+
pub fn add_overflow_physaddr() {
739+
let _ = PhysAddr::new(0x000f_ffff_ffff_ffff) + 0xffff_0000_0000_0000;
740+
}
741+
742+
#[test]
743+
#[should_panic]
744+
pub fn sub_underflow_virtaddr() {
745+
let _ = VirtAddr::new(0) - 1;
746+
}
747+
748+
#[test]
749+
#[should_panic]
750+
pub fn sub_overflow_physaddr() {
751+
let _ = PhysAddr::new(0) - 1;
752+
}
753+
666754
#[test]
667755
pub fn virtaddr_new_truncate() {
668756
assert_eq!(VirtAddr::new_truncate(0), VirtAddr(0));

src/registers/control.rs

+57
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,63 @@ mod x86_64 {
361361
asm!("mov cr3, {}", in(reg) value, options(nostack, preserves_flags));
362362
}
363363
}
364+
365+
/// Update the P4 table address in the CR3 register.
366+
///
367+
/// ## Safety
368+
///
369+
/// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
370+
/// changing the page mapping.
371+
#[inline]
372+
pub unsafe fn update<F>(f: F)
373+
where
374+
F: FnOnce(&mut PhysFrame, &mut Cr3Flags),
375+
{
376+
let (mut frame, mut flags) = Self::read();
377+
f(&mut frame, &mut flags);
378+
unsafe {
379+
Self::write(frame, flags);
380+
}
381+
}
382+
383+
/// Updates the P4 table address in the CR3 register.
384+
///
385+
/// ## Safety
386+
///
387+
/// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
388+
/// changing the page mapping.
389+
/// [`Cr4Flags::PCID`] must be set before calling this method.
390+
#[inline]
391+
pub unsafe fn update_pcid<F>(f: F)
392+
where
393+
F: FnOnce(&mut PhysFrame, &mut Pcid),
394+
{
395+
let (mut frame, mut pcid) = Self::read_pcid();
396+
f(&mut frame, &mut pcid);
397+
unsafe {
398+
Self::write_pcid(frame, pcid);
399+
}
400+
}
401+
402+
/// Updates the P4 table address in the CR3 register without flushing existing TLB entries for
403+
/// the PCID.
404+
///
405+
/// ## Safety
406+
///
407+
/// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
408+
/// changing the page mapping.
409+
/// [`Cr4Flags::PCID`] must be set before calling this method.
410+
#[inline]
411+
pub unsafe fn update_pcid_no_flush<F>(f: F)
412+
where
413+
F: FnOnce(&mut PhysFrame, &mut Pcid),
414+
{
415+
let (mut frame, mut pcid) = Self::read_pcid();
416+
f(&mut frame, &mut pcid);
417+
unsafe {
418+
Self::write_pcid_no_flush(frame, pcid);
419+
}
420+
}
364421
}
365422

366423
impl Cr4 {

src/registers/debug.rs

+13
Original file line numberDiff line numberDiff line change
@@ -499,5 +499,18 @@ mod x86_64 {
499499
asm!("mov dr7, {}", in(reg) value, options(nomem, nostack, preserves_flags));
500500
}
501501
}
502+
503+
/// Update the DR7 value.
504+
///
505+
/// Preserves the value of reserved fields.
506+
#[inline]
507+
pub fn update<F>(f: F)
508+
where
509+
F: FnOnce(&mut Dr7Value),
510+
{
511+
let mut value = Self::read();
512+
f(&mut value);
513+
Self::write(value);
514+
}
502515
}
503516
}

0 commit comments

Comments
 (0)