diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-03-22 16:41:32 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-03-22 16:41:32 +0100 |
commit | e97457545cea0b2ca421da257c83d8f1ef451d85 (patch) | |
tree | f36109d5da79674a286633b61c09250ed64e61d0 /modules | |
parent | 9f0ef3c2fc9ac63e2077663e4dd2953db59347b4 (diff) | |
parent | bdc68b494d6a26c9457f4841ab1a6109b12a33e6 (diff) | |
download | nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.tar nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.tar.gz nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.tar.bz2 nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.tar.lz nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.tar.xz nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.tar.zst nixlib-e97457545cea0b2ca421da257c83d8f1ef451d85.zip |
Merge https://github.com/tpwrules/nixos-apple-silicon
Diffstat (limited to 'modules')
16 files changed, 493 insertions, 27 deletions
diff --git a/modules/nixos-apple-silicon/README.md b/modules/nixos-apple-silicon/README.md index 93b9f6fa1907..becc860ed023 100644 --- a/modules/nixos-apple-silicon/README.md +++ b/modules/nixos-apple-silicon/README.md @@ -9,7 +9,7 @@ Please see the documentation and guide below to get started. ## Documentation * [Release Notes](docs/release-notes.md) -* [Setup, Installation, and Maintenance Guide (2024-02-29)](docs/uefi-standalone.md) +* [Setup, Installation, and Maintenance Guide (2024-03-11)](docs/uefi-standalone.md) ## Credits diff --git a/modules/nixos-apple-silicon/apple-silicon-support/modules/boot-m1n1/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/modules/boot-m1n1/default.nix index 39e94c568a3b..ccbd40bddb8c 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/modules/boot-m1n1/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/modules/boot-m1n1/default.nix @@ -23,7 +23,7 @@ let ''; }; in { - config = { + config = lib.mkIf config.hardware.asahi.enable { # install m1n1 with the boot loader boot.loader.grub.extraFiles = bootFiles; boot.loader.systemd-boot.extraFiles = bootFiles; diff --git a/modules/nixos-apple-silicon/apple-silicon-support/modules/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/modules/default.nix index d6f397671c72..7990556d46b4 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/modules/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/modules/default.nix @@ -8,10 +8,9 @@ ./sound ]; - config = - let + config = let cfg = config.hardware.asahi; - in { + in lib.mkIf cfg.enable { nixpkgs.overlays = lib.mkBefore [ cfg.overlay ]; hardware.asahi.pkgs = @@ -26,6 +25,14 @@ }; options.hardware.asahi = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Enable the basic Asahi Linux components, such as kernel and boot setup. + ''; + }; + pkgsSystem = lib.mkOption { type = lib.types.str; default = "aarch64-linux"; diff --git a/modules/nixos-apple-silicon/apple-silicon-support/modules/kernel/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/modules/kernel/default.nix index a7b0ea574713..619a02634e93 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/modules/kernel/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/modules/kernel/default.nix @@ -2,7 +2,7 @@ { config, pkgs, lib, ... }: { - config = { + config = lib.mkIf config.hardware.asahi.enable { boot.kernelPackages = let pkgs' = config.hardware.asahi.pkgs; in diff --git a/modules/nixos-apple-silicon/apple-silicon-support/modules/mesa/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/modules/mesa/default.nix index 34966d05d7ad..cc3db2b32930 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/modules/mesa/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/modules/mesa/default.nix @@ -3,7 +3,7 @@ config = let isMode = mode: (config.hardware.asahi.useExperimentalGPUDriver && config.hardware.asahi.experimentalGPUInstallMode == mode); - in lib.mkMerge [ + in lib.mkIf config.hardware.asahi.enable (lib.mkMerge [ { # required for proper DRM setup even without GPU driver services.xserver.config = '' @@ -41,7 +41,7 @@ }) ]; }) - ]; + ]); options.hardware.asahi.useExperimentalGPUDriver = lib.mkOption { type = lib.types.bool; diff --git a/modules/nixos-apple-silicon/apple-silicon-support/modules/peripheral-firmware/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/modules/peripheral-firmware/default.nix index 2a478e6d9d77..e10632ff2a5e 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/modules/peripheral-firmware/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/modules/peripheral-firmware/default.nix @@ -1,6 +1,6 @@ { config, pkgs, lib, ... }: { - config = { + config = lib.mkIf config.hardware.asahi.enable { assertions = lib.mkIf config.hardware.asahi.extractPeripheralFirmware [ { assertion = config.hardware.asahi.peripheralFirmwareDirectory != null; message = '' diff --git a/modules/nixos-apple-silicon/apple-silicon-support/modules/sound/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/modules/sound/default.nix index 38e412b9e174..d76e7138d4c9 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/modules/sound/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/modules/sound/default.nix @@ -5,13 +5,13 @@ # disable pulseaudio as the Asahi sound infrastructure can't use it. # if we disable it only if setupAsahiSound is enabled, then infinite # recursion results as pulseaudio enables config.sound by default. - { config.hardware.pulseaudio.enable = false; } + { config.hardware.pulseaudio.enable = (!config.hardware.asahi.enable); } ]; options.hardware.asahi = { setupAsahiSound = lib.mkOption { type = lib.types.bool; - default = config.sound.enable; + default = config.sound.enable && config.hardware.asahi.enable; description = '' Set up the Asahi DSP components so that the speakers and headphone jack work properly and safely. @@ -20,6 +20,8 @@ }; config = let + cfg = config.hardware.asahi; + asahi-audio = pkgs.asahi-audio; # the asahi-audio we use lsp-plugins = pkgs.lsp-plugins; # the lsp-plugins we use @@ -39,7 +41,7 @@ newHotness = builtins.hasAttr "configPackages" options.services.pipewire; lv2Path = lib.makeSearchPath "lib/lv2" [ lsp-plugins pkgs.bankstown-lv2 ]; - in lib.mkIf config.hardware.asahi.setupAsahiSound (lib.mkMerge [ + in lib.mkIf (cfg.setupAsahiSound && cfg.enable) (lib.mkMerge [ { # enable pipewire to run real-time and avoid audible glitches security.rtkit.enable = true; diff --git a/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix index 36e7c0758a85..bb9a05466655 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/default.nix @@ -121,6 +121,10 @@ let { name = "rustc-1.75.0"; patch = ./0001-check-in-new-alloc-for-1.75.0.patch; } + ] ++ lib.optionals (rustAtLeast "1.76.0") [ + { name = "rustc-1.76.0"; + patch = ./rust_1_76_0.patch; + } ] ++ _kernelPatches; inherit configfile; diff --git a/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/rust_1_76_0.patch b/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/rust_1_76_0.patch new file mode 100644 index 000000000000..0ede15025298 --- /dev/null +++ b/modules/nixos-apple-silicon/apple-silicon-support/packages/linux-asahi/rust_1_76_0.patch @@ -0,0 +1,426 @@ +diff --git a/rust/alloc/alloc.rs b/rust/alloc/alloc.rs +index 08eafb3de807..7cf4edb8b786 100644 +--- a/rust/alloc/alloc.rs ++++ b/rust/alloc/alloc.rs +@@ -426,12 +426,14 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { + } + } + ++#[cfg(not(no_global_oom_handling))] + /// Specialize clones into pre-allocated, uninitialized memory. + /// Used by `Box::clone` and `Rc`/`Arc::make_mut`. + pub(crate) trait WriteCloneIntoRaw: Sized { + unsafe fn write_clone_into_raw(&self, target: *mut Self); + } + ++#[cfg(not(no_global_oom_handling))] + impl<T: Clone> WriteCloneIntoRaw for T { + #[inline] + default unsafe fn write_clone_into_raw(&self, target: *mut Self) { +@@ -441,6 +443,7 @@ impl<T: Clone> WriteCloneIntoRaw for T { + } + } + ++#[cfg(not(no_global_oom_handling))] + impl<T: Copy> WriteCloneIntoRaw for T { + #[inline] + unsafe fn write_clone_into_raw(&self, target: *mut Self) { +diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs +index ed7e2f666178..359b8bcdb7a2 100644 +--- a/rust/alloc/boxed.rs ++++ b/rust/alloc/boxed.rs +@@ -1030,10 +1030,18 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { + /// use std::ptr; + /// + /// let x = Box::new(String::from("Hello")); +- /// let p = Box::into_raw(x); ++ /// let ptr = Box::into_raw(x); ++ /// unsafe { ++ /// ptr::drop_in_place(ptr); ++ /// dealloc(ptr as *mut u8, Layout::new::<String>()); ++ /// } ++ /// ``` ++ /// Note: This is equivalent to the following: ++ /// ``` ++ /// let x = Box::new(String::from("Hello")); ++ /// let ptr = Box::into_raw(x); + /// unsafe { +- /// ptr::drop_in_place(p); +- /// dealloc(p as *mut u8, Layout::new::<String>()); ++ /// drop(Box::from_raw(ptr)); + /// } + /// ``` + /// +diff --git a/rust/alloc/collections/mod.rs b/rust/alloc/collections/mod.rs +index 2506065d158a..00ffb3b97365 100644 +--- a/rust/alloc/collections/mod.rs ++++ b/rust/alloc/collections/mod.rs +@@ -150,6 +150,7 @@ fn fmt( + + /// An intermediate trait for specialization of `Extend`. + #[doc(hidden)] ++#[cfg(not(no_global_oom_handling))] + trait SpecExtend<I: IntoIterator> { + /// Extends `self` with the contents of the given iterator. + fn spec_extend(&mut self, iter: I); +diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs +index 65b7a02d0956..6cddaf298118 100644 +--- a/rust/alloc/lib.rs ++++ b/rust/alloc/lib.rs +@@ -157,6 +157,7 @@ + #![feature(std_internals)] + #![feature(str_internals)] + #![feature(strict_provenance)] ++#![feature(trusted_fused)] + #![feature(trusted_len)] + #![feature(trusted_random_access)] + #![feature(try_trait_v2)] +@@ -276,7 +277,7 @@ pub(crate) mod test_helpers { + /// seed not being the same for every RNG invocation too. + pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { + use std::hash::{BuildHasher, Hash, Hasher}; +- let mut hasher = std::collections::hash_map::RandomState::new().build_hasher(); ++ let mut hasher = std::hash::RandomState::new().build_hasher(); + std::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = +diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs +index 65d5ce15828e..3fb1ee104cff 100644 +--- a/rust/alloc/raw_vec.rs ++++ b/rust/alloc/raw_vec.rs +@@ -27,6 +27,16 @@ enum AllocInit { + Zeroed, + } + ++#[repr(transparent)] ++#[cfg_attr(target_pointer_width = "16", rustc_layout_scalar_valid_range_end(0x7fff))] ++#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0x7fff_ffff))] ++#[cfg_attr(target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0x7fff_ffff_ffff_ffff))] ++struct Cap(usize); ++ ++impl Cap { ++ const ZERO: Cap = unsafe { Cap(0) }; ++} ++ + /// A low-level utility for more ergonomically allocating, reallocating, and deallocating + /// a buffer of memory on the heap without having to worry about all the corner cases + /// involved. This type is excellent for building your own data structures like Vec and VecDeque. +@@ -52,7 +62,12 @@ enum AllocInit { + #[allow(missing_debug_implementations)] + pub(crate) struct RawVec<T, A: Allocator = Global> { + ptr: Unique<T>, +- cap: usize, ++ /// Never used for ZSTs; it's `capacity()`'s responsibility to return usize::MAX in that case. ++ /// ++ /// # Safety ++ /// ++ /// `cap` must be in the `0..=isize::MAX` range. ++ cap: Cap, + alloc: A, + } + +@@ -121,7 +136,7 @@ impl<T, A: Allocator> RawVec<T, A> { + /// the returned `RawVec`. + pub const fn new_in(alloc: A) -> Self { + // `cap: 0` means "unallocated". zero-sized types are ignored. +- Self { ptr: Unique::dangling(), cap: 0, alloc } ++ Self { ptr: Unique::dangling(), cap: Cap::ZERO, alloc } + } + + /// Like `with_capacity`, but parameterized over the choice of +@@ -203,7 +218,7 @@ fn allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Self { + // here should change to `ptr.len() / mem::size_of::<T>()`. + Self { + ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }, +- cap: capacity, ++ cap: unsafe { Cap(capacity) }, + alloc, + } + } +@@ -228,7 +243,7 @@ fn try_allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Result<Self, T + // here should change to `ptr.len() / mem::size_of::<T>()`. + Ok(Self { + ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }, +- cap: capacity, ++ cap: unsafe { Cap(capacity) }, + alloc, + }) + } +@@ -240,12 +255,13 @@ fn try_allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Result<Self, T + /// The `ptr` must be allocated (via the given allocator `alloc`), and with the given + /// `capacity`. + /// The `capacity` cannot exceed `isize::MAX` for sized types. (only a concern on 32-bit +- /// systems). ZST vectors may have a capacity up to `usize::MAX`. ++ /// systems). For ZSTs capacity is ignored. + /// If the `ptr` and `capacity` come from a `RawVec` created via `alloc`, then this is + /// guaranteed. + #[inline] + pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self { +- Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap: capacity, alloc } ++ let cap = if T::IS_ZST { Cap::ZERO } else { unsafe { Cap(capacity) } }; ++ Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc } + } + + /// Gets a raw pointer to the start of the allocation. Note that this is +@@ -261,7 +277,7 @@ pub fn ptr(&self) -> *mut T { + /// This will always be `usize::MAX` if `T` is zero-sized. + #[inline(always)] + pub fn capacity(&self) -> usize { +- if T::IS_ZST { usize::MAX } else { self.cap } ++ if T::IS_ZST { usize::MAX } else { self.cap.0 } + } + + /// Returns a shared reference to the allocator backing this `RawVec`. +@@ -270,7 +286,7 @@ pub fn allocator(&self) -> &A { + } + + fn current_memory(&self) -> Option<(NonNull<u8>, Layout)> { +- if T::IS_ZST || self.cap == 0 { ++ if T::IS_ZST || self.cap.0 == 0 { + None + } else { + // We could use Layout::array here which ensures the absence of isize and usize overflows +@@ -280,7 +296,7 @@ fn current_memory(&self) -> Option<(NonNull<u8>, Layout)> { + let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) }; + unsafe { + let align = mem::align_of::<T>(); +- let size = mem::size_of::<T>().unchecked_mul(self.cap); ++ let size = mem::size_of::<T>().unchecked_mul(self.cap.0); + let layout = Layout::from_size_align_unchecked(size, align); + Some((self.ptr.cast().into(), layout)) + } +@@ -404,12 +420,15 @@ fn needs_to_grow(&self, len: usize, additional: usize) -> bool { + additional > self.capacity().wrapping_sub(len) + } + +- fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { ++ /// # Safety: ++ /// ++ /// `cap` must not exceed `isize::MAX`. ++ unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { + // Allocators currently return a `NonNull<[u8]>` whose length matches + // the size requested. If that ever changes, the capacity here should + // change to `ptr.len() / mem::size_of::<T>()`. + self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }; +- self.cap = cap; ++ self.cap = unsafe { Cap(cap) }; + } + + // This method is usually instantiated many times. So we want it to be as +@@ -434,14 +453,15 @@ fn grow_amortized(&mut self, len: usize, additional: usize) -> Result<(), TryRes + + // This guarantees exponential growth. The doubling cannot overflow + // because `cap <= isize::MAX` and the type of `cap` is `usize`. +- let cap = cmp::max(self.cap * 2, required_cap); ++ let cap = cmp::max(self.cap.0 * 2, required_cap); + let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap); + + let new_layout = Layout::array::<T>(cap); + + // `finish_grow` is non-generic over `T`. + let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; +- self.set_ptr_and_cap(ptr, cap); ++ // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than isize::MAX items ++ unsafe { self.set_ptr_and_cap(ptr, cap) }; + Ok(()) + } + +@@ -460,7 +480,10 @@ fn grow_exact(&mut self, len: usize, additional: usize) -> Result<(), TryReserve + + // `finish_grow` is non-generic over `T`. + let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; +- self.set_ptr_and_cap(ptr, cap); ++ // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than isize::MAX items ++ unsafe { ++ self.set_ptr_and_cap(ptr, cap); ++ } + Ok(()) + } + +diff --git a/rust/alloc/vec/into_iter.rs b/rust/alloc/vec/into_iter.rs +index aac0ec16aef1..136bfe94af6c 100644 +--- a/rust/alloc/vec/into_iter.rs ++++ b/rust/alloc/vec/into_iter.rs +@@ -9,7 +9,8 @@ + use core::array; + use core::fmt; + use core::iter::{ +- FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce, ++ FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen, ++ TrustedRandomAccessNoCoerce, + }; + use core::marker::PhantomData; + use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; +@@ -287,9 +288,7 @@ unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item + // Also note the implementation of `Self: TrustedRandomAccess` requires + // that `T: Copy` so reading elements from the buffer doesn't invalidate + // them for `Drop`. +- unsafe { +- if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } +- } ++ unsafe { if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } } + } + } + +@@ -341,6 +340,10 @@ fn is_empty(&self) -> bool { + #[stable(feature = "fused", since = "1.26.0")] + impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} + ++#[doc(hidden)] ++#[unstable(issue = "none", feature = "trusted_fused")] ++unsafe impl<T, A: Allocator> TrustedFused for IntoIter<T, A> {} ++ + #[unstable(feature = "trusted_len", issue = "37572")] + unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {} + +@@ -425,7 +428,10 @@ fn drop(&mut self) { + // also refer to the vec::in_place_collect module documentation to get an overview + #[unstable(issue = "none", feature = "inplace_iteration")] + #[doc(hidden)] +-unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {} ++unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> { ++ const EXPAND_BY: Option<NonZeroUsize> = NonZeroUsize::new(1); ++ const MERGE_BY: Option<NonZeroUsize> = NonZeroUsize::new(1); ++} + + #[unstable(issue = "none", feature = "inplace_iteration")] + #[doc(hidden)] +diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs +index 05c70de0227e..2534ec65500e 100644 +--- a/rust/alloc/vec/mod.rs ++++ b/rust/alloc/vec/mod.rs +@@ -105,6 +105,7 @@ + #[cfg(not(no_global_oom_handling))] + use self::is_zero::IsZero; + ++#[cfg(not(no_global_oom_handling))] + mod is_zero; + + #[cfg(not(no_global_oom_handling))] +@@ -123,7 +124,7 @@ + mod set_len_on_drop; + + #[cfg(not(no_global_oom_handling))] +-use self::in_place_drop::{InPlaceDrop, InPlaceDstBufDrop}; ++use self::in_place_drop::{InPlaceDrop, InPlaceDstDataSrcBufDrop}; + + #[cfg(not(no_global_oom_handling))] + mod in_place_drop; +@@ -1837,7 +1838,32 @@ pub fn dedup_by<F>(&mut self, mut same_bucket: F) + return; + } + +- /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */ ++ // Check if we ever want to remove anything. ++ // This allows to use copy_non_overlapping in next cycle. ++ // And avoids any memory writes if we don't need to remove anything. ++ let mut first_duplicate_idx: usize = 1; ++ let start = self.as_mut_ptr(); ++ while first_duplicate_idx != len { ++ let found_duplicate = unsafe { ++ // SAFETY: first_duplicate always in range [1..len) ++ // Note that we start iteration from 1 so we never overflow. ++ let prev = start.add(first_duplicate_idx.wrapping_sub(1)); ++ let current = start.add(first_duplicate_idx); ++ // We explicitly say in docs that references are reversed. ++ same_bucket(&mut *current, &mut *prev) ++ }; ++ if found_duplicate { ++ break; ++ } ++ first_duplicate_idx += 1; ++ } ++ // Don't need to remove anything. ++ // We cannot get bigger than len. ++ if first_duplicate_idx == len { ++ return; ++ } ++ ++ /* INVARIANT: vec.len() > read > write > write-1 >= 0 */ + struct FillGapOnDrop<'a, T, A: core::alloc::Allocator> { + /* Offset of the element we want to check if it is duplicate */ + read: usize, +@@ -1883,31 +1909,39 @@ fn drop(&mut self) { + } + } + +- let mut gap = FillGapOnDrop { read: 1, write: 1, vec: self }; +- let ptr = gap.vec.as_mut_ptr(); +- + /* Drop items while going through Vec, it should be more efficient than + * doing slice partition_dedup + truncate */ + ++ // Construct gap first and then drop item to avoid memory corruption if `T::drop` panics. ++ let mut gap = ++ FillGapOnDrop { read: first_duplicate_idx + 1, write: first_duplicate_idx, vec: self }; ++ unsafe { ++ // SAFETY: we checked that first_duplicate_idx in bounds before. ++ // If drop panics, `gap` would remove this item without drop. ++ ptr::drop_in_place(start.add(first_duplicate_idx)); ++ } ++ + /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr + * are always in-bounds and read_ptr never aliases prev_ptr */ + unsafe { + while gap.read < len { +- let read_ptr = ptr.add(gap.read); +- let prev_ptr = ptr.add(gap.write.wrapping_sub(1)); ++ let read_ptr = start.add(gap.read); ++ let prev_ptr = start.add(gap.write.wrapping_sub(1)); + +- if same_bucket(&mut *read_ptr, &mut *prev_ptr) { ++ // We explicitly say in docs that references are reversed. ++ let found_duplicate = same_bucket(&mut *read_ptr, &mut *prev_ptr); ++ if found_duplicate { + // Increase `gap.read` now since the drop may panic. + gap.read += 1; + /* We have found duplicate, drop it in-place */ + ptr::drop_in_place(read_ptr); + } else { +- let write_ptr = ptr.add(gap.write); ++ let write_ptr = start.add(gap.write); + +- /* Because `read_ptr` can be equal to `write_ptr`, we either +- * have to use `copy` or conditional `copy_nonoverlapping`. +- * Looks like the first option is faster. */ +- ptr::copy(read_ptr, write_ptr, 1); ++ /* read_ptr cannot be equal to write_ptr because at this point ++ * we guaranteed to skip at least one element (before loop starts). ++ */ ++ ptr::copy_nonoverlapping(read_ptr, write_ptr, 1); + + /* We have filled that place, so go further */ + gap.write += 1; +@@ -2802,6 +2836,7 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec< + <T as SpecFromElem>::from_elem(elem, n, alloc) + } + ++#[cfg(not(no_global_oom_handling))] + trait ExtendFromWithinSpec { + /// # Safety + /// +@@ -2810,6 +2845,7 @@ trait ExtendFromWithinSpec { + unsafe fn spec_extend_from_within(&mut self, src: Range<usize>); + } + ++#[cfg(not(no_global_oom_handling))] + impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> { + default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) { + // SAFETY: +@@ -2829,6 +2865,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> { + } + } + ++#[cfg(not(no_global_oom_handling))] + impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> { + unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) { + let count = src.len(); +@@ -2909,7 +2946,7 @@ fn clone_from(&mut self, other: &Self) { + /// ``` + /// use std::hash::BuildHasher; + /// +-/// let b = std::collections::hash_map::RandomState::new(); ++/// let b = std::hash::RandomState::new(); + /// let v: Vec<u8> = vec![0xa8, 0x3c, 0x09]; + /// let s: &[u8] = &[0xa8, 0x3c, 0x09]; + /// assert_eq!(b.hash_one(v), b.hash_one(s)); diff --git a/modules/nixos-apple-silicon/apple-silicon-support/packages/mesa-asahi-edge/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/packages/mesa-asahi-edge/default.nix index 179d742af7b7..703dfb3711a7 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/packages/mesa-asahi-edge/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/packages/mesa-asahi-edge/default.nix @@ -1,6 +1,7 @@ { lib , fetchFromGitLab , mesa +, meson , llvmPackages }: @@ -19,8 +20,8 @@ domain = "gitlab.freedesktop.org"; owner = "asahi"; repo = "mesa"; - rev = "asahi-20240218"; - hash = "sha256-IMR6x7xYUOp/IBycL8RKs4lbInEh2Xfu6Kjom4S+D/s="; + rev = "asahi-20240228"; + hash = "sha256-wOFJyYfoN6yxE9HaHXLP/0MhjyRvmlb+jPPUke0sbbE="; }; mesonFlags = @@ -36,7 +37,9 @@ # do not want to add the dependencies "-Dlibunwind=disabled" "-Dlmsensors=disabled" - ]; + ] ++ ( # does not compile on nixpkgs stable, doesn't seem mandatory + lib.optional (lib.versionOlder meson.version "1.3.1") + "-Dgallium-rusticl=false"); # replace patches with ones tweaked slightly to apply to this version patches = [ diff --git a/modules/nixos-apple-silicon/apple-silicon-support/packages/uboot-asahi/default.nix b/modules/nixos-apple-silicon/apple-silicon-support/packages/uboot-asahi/default.nix index c3bf0847973f..02075891677d 100644 --- a/modules/nixos-apple-silicon/apple-silicon-support/packages/uboot-asahi/default.nix +++ b/modules/nixos-apple-silicon/apple-silicon-support/packages/uboot-asahi/default.nix @@ -32,8 +32,8 @@ patches = [ ]; - # flag somehow breaks DTC compilation so we remove it - makeFlags = builtins.filter (s: s != "DTC=dtc") o.makeFlags; + # DTC= flag somehow breaks DTC compilation so we remove it + makeFlags = builtins.filter (s: (!(lib.strings.hasPrefix "DTC=" s))) o.makeFlags; preInstall = '' # compress so that m1n1 knows U-Boot's size and can find things after it diff --git a/modules/nixos-apple-silicon/docs/release-notes.md b/modules/nixos-apple-silicon/docs/release-notes.md index 5f0ba4a0033b..0f59c9277b7d 100644 --- a/modules/nixos-apple-silicon/docs/release-notes.md +++ b/modules/nixos-apple-silicon/docs/release-notes.md @@ -2,6 +2,29 @@ This file contains important information for each release. +## 2024-03-11 + +This release updates nixpkgs. + +This release includes patches to correct building of the kernel with Rust 1.76.0 +and fixes for building U-Boot with the latest nixpkgs. Thanks to bkchr for +these patches. + +This release also introduces a `hardware.asahi.enable` configuration option, +which defaults to true. Setting this option to false disables all effects of +the Apple Silicon support module (including ignoring all other options), which +may be useful for multi-system configurations. + +## 2024-03-05 + +This release updates nixpkgs and Mesa. + +This release also includes a patch so that Mesa can build again on NixOS 23.11 +and older nixpkgs versions. + +Support for stable NixOS releases is neither tested nor guaranteed, but patches +to address specific issues are welcome. + ## 2024-02-29 This release updates nixpkgs. diff --git a/modules/nixos-apple-silicon/docs/uefi-standalone.md b/modules/nixos-apple-silicon/docs/uefi-standalone.md index 49bc96ccdc67..9b2f6125661e 100644 --- a/modules/nixos-apple-silicon/docs/uefi-standalone.md +++ b/modules/nixos-apple-silicon/docs/uefi-standalone.md @@ -1,11 +1,11 @@ -# UEFI Boot Standalone NixOS (2024-02-29) +# UEFI Boot Standalone NixOS (2024-03-11) This guide will build and was tested with the following software: * Asahi Linux kernel version 6.6.0-asahi15 -* Asahi Linux's Mesa version 24.1.0_asahi-20240218-1 +* Asahi Linux's Mesa version 24.1.0_asahi-20240228-1 * m1n1 version v1.4.11 * Asahi Linux's U-Boot version 2023.07.02.asahi4-1 -* Nixpkgs, as of 2024-02-26 +* Nixpkgs, as of 2024-03-08 * macOS stub 12.3 NOTE: The latest version of this guide will always be [at its home](https://github.com/tpwrules/nixos-apple-silicon/blob/main/docs/uefi-standalone.md). For more general information about Linux on Apple Silicon Macs, refer to the [Asahi Linux project](https://asahilinux.org/) and [alpha installer release](https://asahilinux.org/2022/03/asahi-linux-alpha-release/). diff --git a/modules/nixos-apple-silicon/flake.lock b/modules/nixos-apple-silicon/flake.lock index 770b3c493737..b65ab5cac056 100644 --- a/modules/nixos-apple-silicon/flake.lock +++ b/modules/nixos-apple-silicon/flake.lock @@ -17,17 +17,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1708984720, - "narHash": "sha256-gJctErLbXx4QZBBbGp78PxtOOzsDaQ+yw1ylNQBuSUY=", + "lastModified": 1709961763, + "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "13aff9b34cc32e59d35c62ac9356e4a41198a538", + "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34", "type": "github" }, "original": { "owner": "nixos", "repo": "nixpkgs", - "rev": "13aff9b34cc32e59d35c62ac9356e4a41198a538", + "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34", "type": "github" } }, diff --git a/modules/nixos-apple-silicon/flake.nix b/modules/nixos-apple-silicon/flake.nix index 5a02396bc94d..55cda17aa8bd 100644 --- a/modules/nixos-apple-silicon/flake.nix +++ b/modules/nixos-apple-silicon/flake.nix @@ -5,7 +5,7 @@ nixpkgs = { # https://hydra.nixos.org/jobset/mobile-nixos/unstable/evals # these evals have a cross-compiled stdenv available - url = "github:nixos/nixpkgs/13aff9b34cc32e59d35c62ac9356e4a41198a538"; + url = "github:nixos/nixpkgs/3030f185ba6a4bf4f18b87f345f104e6a6961f34"; }; rust-overlay = { diff --git a/modules/nixos-apple-silicon/iso-configuration/installer-configuration.nix b/modules/nixos-apple-silicon/iso-configuration/installer-configuration.nix index 2e2410aa4679..7cd6c59a8d57 100644 --- a/modules/nixos-apple-silicon/iso-configuration/installer-configuration.nix +++ b/modules/nixos-apple-silicon/iso-configuration/installer-configuration.nix @@ -123,8 +123,9 @@ PROGRAM ${pkgs.coreutils}/bin/true ''; - # bogus warning when referring to <nixpkgs> - nix.settings.experimental-features = [ "flakes" ]; + # avoid error that flakes must be enabled when nixos-install uses <nixpkgs> + nixpkgs.flake.setNixPath = false; + nixpkgs.flake.setFlakeRegistry = false; # get rid of warning that stateVersion is unset system.stateVersion = lib.mkDefault lib.trivial.release; |