cross-subsystem: - i2c-hid: Make elan touch controllers power on after panel is enabled - dt bindings for STM32MP25 SoC - pci vgaarb: use screen_info helpers - rust pin-init updates - add MEI driver for late binding firmware update/load uapi: - add ioctl for reassigning GEM handles - provide boot_display attribute on boot-up devices core: - document DRM_MODE_PAGE_FLIP_EVENT - add vendor specific recovery method to drm device wedged uevent gem: - Simplify gpuvm locking ttm: - add interface to populate buffers sched: - Fix race condition in trace code atomic: - Reallow no-op async page flips display: - dp: Fix command length video: - Improve pixel-format handling for struct screen_info rust: - drop Opaque<> from ioctl args - Alloc: - BorrowedPage type and AsPageIter traits - Implement Vmalloc::to_page() and VmallocPageIter - DMA/Scatterlist: - Add dma::DataDirection and type alias for dma_addr_t - Abstraction for struct scatterlist and sg_table - DRM: - simplify use of generics - add DriverFile type alias - drop Object::SIZE - Rust: - pin-init tree merge - Various methods for AsBytes and FromBytes traits gpuvm: - Support madvice in Xe driver gpusvm: - fix hmm_pfn_to_map_order usage in gpusvm bridge: - Improve and fix ref counting on bridge management - cdns-dsi: Various improvements to mode setting - Support Solomon SSD2825 plus DT bindings - Support Waveshare DSI2DPI plus DT bindings - Support Content Protection property - display-connector: Improve DP display detection - Add support for Radxa Ra620 plus DT bindings - adv7511: Provide SPD and HDMI infoframes - it6505: Replace crypto_shash with sha() - synopsys: Add support for DW DPTX Controller plus DT bindings - adv7511: Write full Audio infoframe - ite6263: Support vendor-specific infoframes - simple: Add support for Realtek RTD2171 DP-to-HDMI plus DT bindings panel: - panel-edp: Support mt8189 Chromebooks; Support BOE NV140WUM-N64; Support SHP LQ134Z1; Fixes - panel-simple: Support Olimex LCD-OLinuXino-5CTS plus DT bindings - Support Samsung AMS561RA01 - Support Hydis HV101HD1 plus DT bindings - ilitek-ili9881c: Refactor mode setting; Add support for Bestar BSD1218-A101KL68 LCD plus DT bindings - lvds: Add support for Ampire AMP19201200B5TZQW-T03 to DT bindings - edp: Add support for additonal mt8189 Chromebook panels - lvds: Add DT bindings for EDT ETML0700Z8DHA amdgpu: - add CRIU support for gem objects - RAS updates - VCN SRAM load fixes - EDID read fixes - eDP ALPM support - Documentation updates - Rework PTE flag generation - DCE6 fixes - VCN devcoredump cleanup - MMHUB client id fixes - VCN 5.0.1 RAS support - SMU 13.0.x updates - Expanded PCIe DPC support - Expanded VCN reset support - VPE per queue reset support - give kernel jobs unique id for tracing - pre-populate exported buffers - cyan skillfish updates - make vbios build number available in sysfs - userq updates - HDCP updates - support MMIO remap page as ttm pool - JPEG parser updates - DCE6 DC updates - use devm for i2c buses - GPUVM locking updates - Drop non-DC DCE11 code - improve fallback handling for pixel encoding amdkfd: - SVM/page migration fixes - debugfs fixes - add CRIO support for gem objects - SVM updates radeon: - use dev_warn_once in CS parsers xe: - add madvise interface - add DRM_IOCTL_XE_VM_QUERY_MEMORY_RANGE_ATTRS to query VMA count and memory attributes - drop L# bank mask reporting from media GT3 on Xe3+. - add SLPC power_profile sysfs interface - add configs attribs to add post/mid context-switch commands - handle firmware reported hardware errors notifying userspace with device wedged uevent - use same dir structure across sysfs/debugfs - cleanup and future proof vram region init - add G-states and PCI link states to debugfs - Add SRIOV support for CCS surfaces on Xe2+ - Enable SRIOV PF mode by default on supported platforms - move flush to common code - extended core workarounds for Xe2/3 - use DRM scheduler for delayed GT TLB invalidations - configs improvements and allow VF device enablement - prep work to expose mmio regions to userspace - VF migration support added - prepare GPU SVM for THP migration - start fixing XE_PAGE_SIZE vs PAGE_SIZE - add PSMI support for hw validation - resize VF bars to max possible size according to number of VFs - Ensure GT is in C0 during resume - pre-populate exported buffers - replace xe_hmm with gpusvm - add more SVM GT stats to debugfs - improve fake pci and WA kunnit handle for new platform testing - Test GuC to GuC comms to add debugging - use attribute groups to simplify sysfs registration - add Late Binding firmware code to interact with MEI i915: - apply multiple JSL/EHL/Gen7/Gen6 workarounds properly - protect against overflow in active_engine() - Use try_cmpxchg64() in __active_lookup() - include GuC registers in error state - get rid of dev->struct_mutex - iopoll: generalize read_poll_timout - lots more display refactoring - Reject HBR3 in any eDP Panel - Prune modes for YUV420 - Display Wa fix, additions, and updates - DP: Fix 2.7 Gbps link training on g4x - DP: Adjust the idle pattern handling - DP: Shuffle the link training code a bit - Don't set/read the DSI C clock divider on GLK - Enable_psr kernel parameter changes - Type-C enabled/disconnected dp-alt sink - Wildcat Lake enabling - DP HDR updates - DRAM detection - wait PSR idle on dsb commit - Remove FBC modulo 4 restriction for ADL-P+ - panic: refactor framebuffer allocation habanalabs: - debug/visibility improvements - vmalloc-backed coherent mmap support - HLDIO infrastructure nova-core: - various register!() macro improvements - minor vbios/firmware fixes/refactoring - advance firmware boot stages; process Booter and patch signatures - process GSP and GSP bootloader - Add r570.144 firmware bindings and update to it - Move GSP boot code to own module - Use new pin-init features to store driver's private data in a single allocation - Update ARef import from sync::aref nova-drm: - Update ARef import from sync::aref tyr: - initial driver skeleton for a rust driver for ARM Mali GPUs - capable of powering up, query metadata and provide it to userspace. msm: - GPU and Core: - in DT bindings describe clocks per GPU type - GMU bandwidth voting for x1-85 - a623/a663 speedbins - cleanup some remaining no-iommu leftovers after VM_BIND conversion - fix GEM obj 32b size truncation - add missing VM_BIND param validation - IFPC for x1-85 and a750 - register xml and gen_header.py sync from mesa - Display: - add missing bindings for display on SC8180X - added DisplayPort MST bindings - conversion from round_rate() to determine_rate() amdxdna: - add IOCTL_AMDXDNA_GET_ARRAY - support user space allocated buffers - streamline PM interfaces - Refactoring wrt. hardware contexts - improve error reporting nouveau: - use GSP firmware by default - improve error reporting - Pre-populate exported buffers ast: - Clean up detection of DRAM config exynos: - add DSIM bridge driver support for Exynos7870 - Document Exynos7870 DSIM compatible in dt-binding panthor: - Print task/pid on errors - Add support for Mali G710, G510, G310, Gx15, Gx20, Gx25 - Improve cache flushing - Fail VM bind if BO has offset renesas: - convert to RUNTIME_PM_OPS rcar-du: - Make number of lanes configurable - Use RUNTIME_PM_OPS - Add support for DSI commands rocket: - Add driver for Rockchip NPU plus DT bindings - Use kfree() and sizeof() correctly - Test DMA status rockchip: - dsi2: Add support for RK3576 plus DT bindings - Add support for RK3588 DPTX output tidss: - Use crtc_ fields for programming display mode - Remove other drivers from aperture pixpaper: - Add support for Mayqueen Pixpaper plus DT bindings v3d: - Support querying nubmer of GPU resets for KHR_robustness stm: - Clean up logging - ltdc: Add support support for STM32MP257F-EV1 plus DT bindings sitronix: - st7571-i2c: Add support for inverted displays and 2-bit grayscale tidss: - Convert to kernel's FIELD_ macros vesadrm: - Support 8-bit palette mode imagination: - Improve power management - Add support for TH1520 GPU - Support Risc-V architectures v3d: - Improve job management and locking vkms: - Support variants of ARGB8888, ARGB16161616, RGB565, RGB888 and P01x - Spport YUV with 16-bit components -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmjcpjkACgkQDHTzWXnE hr7Q7g/5AcxXqLUx7wvmDga9TpzIjDD+C+MOt568RpFQ9cYprI+/86ma7ELCpuNe dVgeobxQb/jyhf4acdBU+t5aZz+j8VPhPtIPrPY2kOVDuL1NfeQNS8VmGNpFhR+0 6hqVrtfvbYdLBrAHrU/V/RwZlBJvI/D/I2QGuvZZwWzCBgYd4u4bGuRyBCvGDxOD CTPaEqYyzjvpVuzu7AGQk655WkZQnyPmiezIl2lit1meEMMMv80HePkyWHclZo7Q hMqsEasSp5w5Q5EpYqVr1z5IdBAV1O53oor9W573J3kEoB4o1zEsTPfLO4N1dgXo bfvc24uW3zyChWY2hWyRKvOzvAoClnjfY6whv9NRP0Qi4UjzhLlNOpmhm9cst/J+ uj2Nn8UJtyvFJbTmDvoocpgdhq2mkGKdIVhVQ6tG7PjihFmyQRF7PJZjb+0Vee7L 53F0c4d6HiBI4DHa+lH6fgQUBspIvSfmcnR0ACg29NByib+JEoPSPb4ET+uZ8lLd IbQvNiCdnUduYDCKfo5ea/FesP8AXy1KfSa+z7oEEFYHbbkc7PSztUagEyZdS/yS FnnYqmo/DidmyM4nxDQUII+UDqjng7fo+l4BzIhL12pR693KzCf0mexMr6SA24ny gasN97923OTle1J9xrPrKavkx6WjswZCvOaG7ZbnJB47ydJVu5w= =ZVKY -----END PGP SIGNATURE----- Merge tag 'drm-next-2025-10-01' of https://gitlab.freedesktop.org/drm/kernel Pull drm updates from Dave Airlie: "cross-subsystem: - i2c-hid: Make elan touch controllers power on after panel is enabled - dt bindings for STM32MP25 SoC - pci vgaarb: use screen_info helpers - rust pin-init updates - add MEI driver for late binding firmware update/load uapi: - add ioctl for reassigning GEM handles - provide boot_display attribute on boot-up devices core: - document DRM_MODE_PAGE_FLIP_EVENT - add vendor specific recovery method to drm device wedged uevent gem: - Simplify gpuvm locking ttm: - add interface to populate buffers sched: - Fix race condition in trace code atomic: - Reallow no-op async page flips display: - dp: Fix command length video: - Improve pixel-format handling for struct screen_info rust: - drop Opaque<> from ioctl args - Alloc: - BorrowedPage type and AsPageIter traits - Implement Vmalloc::to_page() and VmallocPageIter - DMA/Scatterlist: - Add dma::DataDirection and type alias for dma_addr_t - Abstraction for struct scatterlist and sg_table - DRM: - simplify use of generics - add DriverFile type alias - drop Object::SIZE - Rust: - pin-init tree merge - Various methods for AsBytes and FromBytes traits gpuvm: - Support madvice in Xe driver gpusvm: - fix hmm_pfn_to_map_order usage in gpusvm bridge: - Improve and fix ref counting on bridge management - cdns-dsi: Various improvements to mode setting - Support Solomon SSD2825 plus DT bindings - Support Waveshare DSI2DPI plus DT bindings - Support Content Protection property - display-connector: Improve DP display detection - Add support for Radxa Ra620 plus DT bindings - adv7511: Provide SPD and HDMI infoframes - it6505: Replace crypto_shash with sha() - synopsys: Add support for DW DPTX Controller plus DT bindings - adv7511: Write full Audio infoframe - ite6263: Support vendor-specific infoframes - simple: Add support for Realtek RTD2171 DP-to-HDMI plus DT bindings panel: - panel-edp: Support mt8189 Chromebooks; Support BOE NV140WUM-N64; Support SHP LQ134Z1; Fixes - panel-simple: Support Olimex LCD-OLinuXino-5CTS plus DT bindings - Support Samsung AMS561RA01 - Support Hydis HV101HD1 plus DT bindings - ilitek-ili9881c: Refactor mode setting; Add support for Bestar BSD1218-A101KL68 LCD plus DT bindings - lvds: Add support for Ampire AMP19201200B5TZQW-T03 to DT bindings - edp: Add support for additonal mt8189 Chromebook panels - lvds: Add DT bindings for EDT ETML0700Z8DHA amdgpu: - add CRIU support for gem objects - RAS updates - VCN SRAM load fixes - EDID read fixes - eDP ALPM support - Documentation updates - Rework PTE flag generation - DCE6 fixes - VCN devcoredump cleanup - MMHUB client id fixes - VCN 5.0.1 RAS support - SMU 13.0.x updates - Expanded PCIe DPC support - Expanded VCN reset support - VPE per queue reset support - give kernel jobs unique id for tracing - pre-populate exported buffers - cyan skillfish updates - make vbios build number available in sysfs - userq updates - HDCP updates - support MMIO remap page as ttm pool - JPEG parser updates - DCE6 DC updates - use devm for i2c buses - GPUVM locking updates - Drop non-DC DCE11 code - improve fallback handling for pixel encoding amdkfd: - SVM/page migration fixes - debugfs fixes - add CRIO support for gem objects - SVM updates radeon: - use dev_warn_once in CS parsers xe: - add madvise interface - add DRM_IOCTL_XE_VM_QUERY_MEMORY_RANGE_ATTRS to query VMA count and memory attributes - drop L# bank mask reporting from media GT3 on Xe3+. - add SLPC power_profile sysfs interface - add configs attribs to add post/mid context-switch commands - handle firmware reported hardware errors notifying userspace with device wedged uevent - use same dir structure across sysfs/debugfs - cleanup and future proof vram region init - add G-states and PCI link states to debugfs - Add SRIOV support for CCS surfaces on Xe2+ - Enable SRIOV PF mode by default on supported platforms - move flush to common code - extended core workarounds for Xe2/3 - use DRM scheduler for delayed GT TLB invalidations - configs improvements and allow VF device enablement - prep work to expose mmio regions to userspace - VF migration support added - prepare GPU SVM for THP migration - start fixing XE_PAGE_SIZE vs PAGE_SIZE - add PSMI support for hw validation - resize VF bars to max possible size according to number of VFs - Ensure GT is in C0 during resume - pre-populate exported buffers - replace xe_hmm with gpusvm - add more SVM GT stats to debugfs - improve fake pci and WA kunnit handle for new platform testing - Test GuC to GuC comms to add debugging - use attribute groups to simplify sysfs registration - add Late Binding firmware code to interact with MEI i915: - apply multiple JSL/EHL/Gen7/Gen6 workarounds properly - protect against overflow in active_engine() - Use try_cmpxchg64() in __active_lookup() - include GuC registers in error state - get rid of dev->struct_mutex - iopoll: generalize read_poll_timout - lots more display refactoring - Reject HBR3 in any eDP Panel - Prune modes for YUV420 - Display Wa fix, additions, and updates - DP: Fix 2.7 Gbps link training on g4x - DP: Adjust the idle pattern handling - DP: Shuffle the link training code a bit - Don't set/read the DSI C clock divider on GLK - Enable_psr kernel parameter changes - Type-C enabled/disconnected dp-alt sink - Wildcat Lake enabling - DP HDR updates - DRAM detection - wait PSR idle on dsb commit - Remove FBC modulo 4 restriction for ADL-P+ - panic: refactor framebuffer allocation habanalabs: - debug/visibility improvements - vmalloc-backed coherent mmap support - HLDIO infrastructure nova-core: - various register!() macro improvements - minor vbios/firmware fixes/refactoring - advance firmware boot stages; process Booter and patch signatures - process GSP and GSP bootloader - Add r570.144 firmware bindings and update to it - Move GSP boot code to own module - Use new pin-init features to store driver's private data in a single allocation - Update ARef import from sync::aref nova-drm: - Update ARef import from sync::aref tyr: - initial driver skeleton for a rust driver for ARM Mali GPUs - capable of powering up, query metadata and provide it to userspace. msm: - GPU and Core: - in DT bindings describe clocks per GPU type - GMU bandwidth voting for x1-85 - a623/a663 speedbins - cleanup some remaining no-iommu leftovers after VM_BIND conversion - fix GEM obj 32b size truncation - add missing VM_BIND param validation - IFPC for x1-85 and a750 - register xml and gen_header.py sync from mesa - Display: - add missing bindings for display on SC8180X - added DisplayPort MST bindings - conversion from round_rate() to determine_rate() amdxdna: - add IOCTL_AMDXDNA_GET_ARRAY - support user space allocated buffers - streamline PM interfaces - Refactoring wrt. hardware contexts - improve error reporting nouveau: - use GSP firmware by default - improve error reporting - Pre-populate exported buffers ast: - Clean up detection of DRAM config exynos: - add DSIM bridge driver support for Exynos7870 - Document Exynos7870 DSIM compatible in dt-binding panthor: - Print task/pid on errors - Add support for Mali G710, G510, G310, Gx15, Gx20, Gx25 - Improve cache flushing - Fail VM bind if BO has offset renesas: - convert to RUNTIME_PM_OPS rcar-du: - Make number of lanes configurable - Use RUNTIME_PM_OPS - Add support for DSI commands rocket: - Add driver for Rockchip NPU plus DT bindings - Use kfree() and sizeof() correctly - Test DMA status rockchip: - dsi2: Add support for RK3576 plus DT bindings - Add support for RK3588 DPTX output tidss: - Use crtc_ fields for programming display mode - Remove other drivers from aperture pixpaper: - Add support for Mayqueen Pixpaper plus DT bindings v3d: - Support querying nubmer of GPU resets for KHR_robustness stm: - Clean up logging - ltdc: Add support support for STM32MP257F-EV1 plus DT bindings sitronix: - st7571-i2c: Add support for inverted displays and 2-bit grayscale tidss: - Convert to kernel's FIELD_ macros vesadrm: - Support 8-bit palette mode imagination: - Improve power management - Add support for TH1520 GPU - Support Risc-V architectures v3d: - Improve job management and locking vkms: - Support variants of ARGB8888, ARGB16161616, RGB565, RGB888 and P01x - Spport YUV with 16-bit components" * tag 'drm-next-2025-10-01' of https://gitlab.freedesktop.org/drm/kernel: (1455 commits) drm/amd: Add name to modes from amdgpu_connector_add_common_modes() drm/amd: Drop some common modes from amdgpu_connector_add_common_modes() drm/amdgpu: update MODULE_PARM_DESC for freesync_video drm/amd: Use dynamic array size declaration for amdgpu_connector_add_common_modes() drm/amd/display: Share dce100_validate_global with DCE6-8 drm/amd/display: Share dce100_validate_bandwidth with DCE6-8 drm/amdgpu: Fix fence signaling race condition in userqueue amd/amdkfd: enhance kfd process check in switch partition amd/amdkfd: resolve a race in amdgpu_amdkfd_device_fini_sw drm/amd/display: Reject modes with too high pixel clock on DCE6-10 drm/amd: Drop unnecessary check in amdgpu_connector_add_common_modes() drm/amd/display: Only enable common modes for eDP and LVDS drm/amdgpu: remove the redeclaration of variable i drm/amdgpu/userq: assign an error code for invalid userq va drm/amdgpu: revert "rework reserved VMID handling" v2 drm/amdgpu: remove leftover from enforcing isolation by VMID drm/amdgpu: Add fallback to pipe reset if KCQ ring reset fails accel/habanalabs: add Infineon version check accel/habanalabs/gaudi2: read preboot status after recovering from dirty state accel/habanalabs: add HL_GET_P_STATE passthrough type ...
256 lines
9.2 KiB
Rust
256 lines
9.2 KiB
Rust
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
//! Allocator support.
|
|
//!
|
|
//! Documentation for the kernel's memory allocators can found in the "Memory Allocation Guide"
|
|
//! linked below. For instance, this includes the concept of "get free page" (GFP) flags and the
|
|
//! typical application of the different kernel allocators.
|
|
//!
|
|
//! Reference: <https://docs.kernel.org/core-api/memory-allocation.html>
|
|
|
|
use super::Flags;
|
|
use core::alloc::Layout;
|
|
use core::ptr;
|
|
use core::ptr::NonNull;
|
|
|
|
use crate::alloc::{AllocError, Allocator};
|
|
use crate::bindings;
|
|
use crate::page;
|
|
use crate::pr_warn;
|
|
|
|
const ARCH_KMALLOC_MINALIGN: usize = bindings::ARCH_KMALLOC_MINALIGN;
|
|
|
|
mod iter;
|
|
pub use self::iter::VmallocPageIter;
|
|
|
|
/// The contiguous kernel allocator.
|
|
///
|
|
/// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also
|
|
/// supports larger allocations up to `bindings::KMALLOC_MAX_SIZE`, which is hardware specific.
|
|
///
|
|
/// For more details see [self].
|
|
pub struct Kmalloc;
|
|
|
|
/// The virtually contiguous kernel allocator.
|
|
///
|
|
/// `Vmalloc` allocates pages from the page level allocator and maps them into the contiguous kernel
|
|
/// virtual space. It is typically used for large allocations. The memory allocated with this
|
|
/// allocator is not physically contiguous.
|
|
///
|
|
/// For more details see [self].
|
|
pub struct Vmalloc;
|
|
|
|
/// The kvmalloc kernel allocator.
|
|
///
|
|
/// `KVmalloc` attempts to allocate memory with `Kmalloc` first, but falls back to `Vmalloc` upon
|
|
/// failure. This allocator is typically used when the size for the requested allocation is not
|
|
/// known and may exceed the capabilities of `Kmalloc`.
|
|
///
|
|
/// For more details see [self].
|
|
pub struct KVmalloc;
|
|
|
|
/// # Invariants
|
|
///
|
|
/// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
|
|
struct ReallocFunc(
|
|
unsafe extern "C" fn(*const crate::ffi::c_void, usize, u32) -> *mut crate::ffi::c_void,
|
|
);
|
|
|
|
impl ReallocFunc {
|
|
// INVARIANT: `krealloc` satisfies the type invariants.
|
|
const KREALLOC: Self = Self(bindings::krealloc);
|
|
|
|
// INVARIANT: `vrealloc` satisfies the type invariants.
|
|
const VREALLOC: Self = Self(bindings::vrealloc);
|
|
|
|
// INVARIANT: `kvrealloc` satisfies the type invariants.
|
|
const KVREALLOC: Self = Self(bindings::kvrealloc);
|
|
|
|
/// # Safety
|
|
///
|
|
/// This method has the same safety requirements as [`Allocator::realloc`].
|
|
///
|
|
/// # Guarantees
|
|
///
|
|
/// This method has the same guarantees as `Allocator::realloc`. Additionally
|
|
/// - it accepts any pointer to a valid memory allocation allocated by this function.
|
|
/// - memory allocated by this function remains valid until it is passed to this function.
|
|
#[inline]
|
|
unsafe fn call(
|
|
&self,
|
|
ptr: Option<NonNull<u8>>,
|
|
layout: Layout,
|
|
old_layout: Layout,
|
|
flags: Flags,
|
|
) -> Result<NonNull<[u8]>, AllocError> {
|
|
let size = layout.size();
|
|
let ptr = match ptr {
|
|
Some(ptr) => {
|
|
if old_layout.size() == 0 {
|
|
ptr::null()
|
|
} else {
|
|
ptr.as_ptr()
|
|
}
|
|
}
|
|
None => ptr::null(),
|
|
};
|
|
|
|
// SAFETY:
|
|
// - `self.0` is one of `krealloc`, `vrealloc`, `kvrealloc` and thus only requires that
|
|
// `ptr` is NULL or valid.
|
|
// - `ptr` is either NULL or valid by the safety requirements of this function.
|
|
//
|
|
// GUARANTEE:
|
|
// - `self.0` is one of `krealloc`, `vrealloc`, `kvrealloc`.
|
|
// - Those functions provide the guarantees of this function.
|
|
let raw_ptr = unsafe {
|
|
// If `size == 0` and `ptr != NULL` the memory behind the pointer is freed.
|
|
self.0(ptr.cast(), size, flags.0).cast()
|
|
};
|
|
|
|
let ptr = if size == 0 {
|
|
crate::alloc::dangling_from_layout(layout)
|
|
} else {
|
|
NonNull::new(raw_ptr).ok_or(AllocError)?
|
|
};
|
|
|
|
Ok(NonNull::slice_from_raw_parts(ptr, size))
|
|
}
|
|
}
|
|
|
|
impl Kmalloc {
|
|
/// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of
|
|
/// `layout`.
|
|
pub fn aligned_layout(layout: Layout) -> Layout {
|
|
// Note that `layout.size()` (after padding) is guaranteed to be a multiple of
|
|
// `layout.align()` which together with the slab guarantees means that `Kmalloc` will return
|
|
// a properly aligned object (see comments in `kmalloc()` for more information).
|
|
layout.pad_to_align()
|
|
}
|
|
}
|
|
|
|
// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
|
|
// - memory remains valid until it is explicitly freed,
|
|
// - passing a pointer to a valid memory allocation is OK,
|
|
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
|
|
unsafe impl Allocator for Kmalloc {
|
|
const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN;
|
|
|
|
#[inline]
|
|
unsafe fn realloc(
|
|
ptr: Option<NonNull<u8>>,
|
|
layout: Layout,
|
|
old_layout: Layout,
|
|
flags: Flags,
|
|
) -> Result<NonNull<[u8]>, AllocError> {
|
|
let layout = Kmalloc::aligned_layout(layout);
|
|
|
|
// SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`.
|
|
unsafe { ReallocFunc::KREALLOC.call(ptr, layout, old_layout, flags) }
|
|
}
|
|
}
|
|
|
|
impl Vmalloc {
|
|
/// Convert a pointer to a [`Vmalloc`] allocation to a [`page::BorrowedPage`].
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::ptr::{NonNull, from_mut};
|
|
/// # use kernel::{page, prelude::*};
|
|
/// use kernel::alloc::allocator::Vmalloc;
|
|
///
|
|
/// let mut vbox = VBox::<[u8; page::PAGE_SIZE]>::new_uninit(GFP_KERNEL)?;
|
|
///
|
|
/// {
|
|
/// // SAFETY: By the type invariant of `Box` the inner pointer of `vbox` is non-null.
|
|
/// let ptr = unsafe { NonNull::new_unchecked(from_mut(&mut *vbox)) };
|
|
///
|
|
/// // SAFETY:
|
|
/// // `ptr` is a valid pointer to a `Vmalloc` allocation.
|
|
/// // `ptr` is valid for the entire lifetime of `page`.
|
|
/// let page = unsafe { Vmalloc::to_page(ptr.cast()) };
|
|
///
|
|
/// // SAFETY: There is no concurrent read or write to the same page.
|
|
/// unsafe { page.fill_zero_raw(0, page::PAGE_SIZE)? };
|
|
/// }
|
|
/// # Ok::<(), Error>(())
|
|
/// ```
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// - `ptr` must be a valid pointer to a [`Vmalloc`] allocation.
|
|
/// - `ptr` must remain valid for the entire duration of `'a`.
|
|
pub unsafe fn to_page<'a>(ptr: NonNull<u8>) -> page::BorrowedPage<'a> {
|
|
// SAFETY: `ptr` is a valid pointer to `Vmalloc` memory.
|
|
let page = unsafe { bindings::vmalloc_to_page(ptr.as_ptr().cast()) };
|
|
|
|
// SAFETY: `vmalloc_to_page` returns a valid pointer to a `struct page` for a valid pointer
|
|
// to `Vmalloc` memory.
|
|
let page = unsafe { NonNull::new_unchecked(page) };
|
|
|
|
// SAFETY:
|
|
// - `page` is a valid pointer to a `struct page`, given that by the safety requirements of
|
|
// this function `ptr` is a valid pointer to a `Vmalloc` allocation.
|
|
// - By the safety requirements of this function `ptr` is valid for the entire lifetime of
|
|
// `'a`.
|
|
unsafe { page::BorrowedPage::from_raw(page) }
|
|
}
|
|
}
|
|
|
|
// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
|
|
// - memory remains valid until it is explicitly freed,
|
|
// - passing a pointer to a valid memory allocation is OK,
|
|
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
|
|
unsafe impl Allocator for Vmalloc {
|
|
const MIN_ALIGN: usize = kernel::page::PAGE_SIZE;
|
|
|
|
#[inline]
|
|
unsafe fn realloc(
|
|
ptr: Option<NonNull<u8>>,
|
|
layout: Layout,
|
|
old_layout: Layout,
|
|
flags: Flags,
|
|
) -> Result<NonNull<[u8]>, AllocError> {
|
|
// TODO: Support alignments larger than PAGE_SIZE.
|
|
if layout.align() > bindings::PAGE_SIZE {
|
|
pr_warn!("Vmalloc does not support alignments larger than PAGE_SIZE yet.\n");
|
|
return Err(AllocError);
|
|
}
|
|
|
|
// SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously
|
|
// allocated with this `Allocator`.
|
|
unsafe { ReallocFunc::VREALLOC.call(ptr, layout, old_layout, flags) }
|
|
}
|
|
}
|
|
|
|
// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
|
|
// - memory remains valid until it is explicitly freed,
|
|
// - passing a pointer to a valid memory allocation is OK,
|
|
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
|
|
unsafe impl Allocator for KVmalloc {
|
|
const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN;
|
|
|
|
#[inline]
|
|
unsafe fn realloc(
|
|
ptr: Option<NonNull<u8>>,
|
|
layout: Layout,
|
|
old_layout: Layout,
|
|
flags: Flags,
|
|
) -> Result<NonNull<[u8]>, AllocError> {
|
|
// `KVmalloc` may use the `Kmalloc` backend, hence we have to enforce a `Kmalloc`
|
|
// compatible layout.
|
|
let layout = Kmalloc::aligned_layout(layout);
|
|
|
|
// TODO: Support alignments larger than PAGE_SIZE.
|
|
if layout.align() > bindings::PAGE_SIZE {
|
|
pr_warn!("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n");
|
|
return Err(AllocError);
|
|
}
|
|
|
|
// SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously
|
|
// allocated with this `Allocator`.
|
|
unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) }
|
|
}
|
|
}
|