amdgpu/linux-kpi: replace remaining stubs with real implementations

- Implement krealloc in linux-kpi memory.rs with GFP-aware tracker lookup,
  copying, and zeroing of grown regions; add krealloc declaration to slab.h
- Align __GFP_ZERO/__GFP_NOWARN and GFP_* values between linux-kpi/slab.h
  and redox_glue.h; make __GFP_ZERO a meaningful flag bit
- Add missing POSIX/errno base constants (EFBIG, EISDIR, ESPIPE, etc.) to
  linux-kpi linux/errno.h so firmware-size checks and other drivers compile
- Harden linux-kpi bug.h: BUG()/BUG_ON() abort, WARN_ON_ONCE only warns once,
  BUILD_BUG_ON uses _Static_assert
- Harden redox_glue.h: add PCI_COMMAND_* flags, CONFIG_HZ/HZ, jiffies
  conversion macros, once-only WARN_ON_ONCE, _Static_assert BUILD_BUG_ON
- Implement redox_pci_enable_device/redox_pci_set_master with real local state
  and command-bit updates; document pcid-spawner pre-enable
- Remove realloc-only krealloc from redox_stubs.c; it now links from linux-kpi
- Fix wait_for_completion_timeout to interpret timeout as jiffies and convert
  to milliseconds, and update msecs/usecs_to_jiffies to use HZ
- Stage previously completed firmware-loader path deps and constructor fix
- Stage base and relibc submodule pointer updates from prior work
This commit is contained in:
2026-07-10 19:44:39 +03:00
parent 705d15ec1f
commit 7c2ea9b5e3
10 changed files with 237 additions and 29 deletions
+38 -3
View File
@@ -60,9 +60,18 @@ typedef unsigned int gfp_t;
#define GFP_KERNEL 0U
#define GFP_ATOMIC 1U
#define GFP_DMA32 2U
#define GFP_NOWAIT 3U
#define GFP_HIGHUSER 3U
#define GFP_NOWAIT 4U
#define GFP_DMA 5U
#define GFP_KERNEL_ACCOUNT 0U
#ifndef __GFP_NOWARN
#define __GFP_NOWARN 0x200U
#endif
#ifndef __GFP_ZERO
#define __GFP_ZERO 0x100U
#endif
extern void *kmalloc(size_t size, unsigned int flags);
extern void *kzalloc(size_t size, unsigned int flags);
extern void kfree(const void *ptr);
@@ -286,6 +295,17 @@ extern bool pci_has_quirk(struct pci_dev *dev, u64 flag);
#define IORESOURCE_MEM_64 0x00040000U
#define IORESOURCE_PREFETCH 0x00001000U
#define PCI_COMMAND_IO 0x0001U
#define PCI_COMMAND_MEMORY 0x0002U
#define PCI_COMMAND_MASTER 0x0004U
#define PCI_COMMAND_SPECIAL 0x0008U
#define PCI_COMMAND_INVALIDATE 0x0010U
#define PCI_COMMAND_VGA_PALETTE 0x0020U
#define PCI_COMMAND_PARITY 0x0040U
#define PCI_COMMAND_SERR 0x0100U
#define PCI_COMMAND_FAST_BACK 0x0200U
#define PCI_COMMAND_INTX_DISABLE 0x0400U
/* ---- Firmware loading — maps to scheme:firmware ---- */
struct firmware {
size_t size;
@@ -413,6 +433,13 @@ extern unsigned long redox_wait_for_completion_timeout(struct completion *c, uns
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define PAGE_ALIGN(x) ALIGN((x), PAGE_SIZE)
/* ---- Time / jiffies ---- */
#define CONFIG_HZ 1000
#define HZ CONFIG_HZ
#define jiffies_to_msecs(j) ((unsigned long)(j) * 1000UL / HZ)
#define jiffies_to_usecs(j) ((unsigned long)(j) * 1000000UL / HZ)
/* ---- msleep, udelay — implemented in redox_stubs.c ---- */
extern void msleep(unsigned int msecs);
extern void udelay(unsigned long usecs);
@@ -542,9 +569,17 @@ static inline int list_empty(const struct list_head *head) {
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define WARN_ON(condition) ({ int __ret = !!(condition); if (__ret) fprintf(stderr, "WARN_ON: %s at %s:%d\n", #condition, __FILE__, __LINE__); __ret; })
#define WARN_ON_ONCE(condition) WARN_ON(condition)
#define WARN_ON_ONCE(condition) ({ \
static bool __warned; \
int __ret = !!(condition) && !__warned; \
if (__ret) { \
__warned = true; \
fprintf(stderr, "WARN_ON_ONCE: %s at %s:%d\n", #condition, __FILE__, __LINE__); \
} \
__ret; \
})
#define BUG_ON(condition) do { if (condition) { fprintf(stderr, "BUG: %s at %s:%d\n", #condition, __FILE__, __LINE__); abort(); } } while (0)
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
#define BUILD_BUG_ON(condition) _Static_assert(!(condition), "BUILD_BUG_ON failed: " #condition)
/* ---- Enum constants ---- */
#define DRM_MODE_DPMS_ON 0
+34 -15
View File
@@ -118,12 +118,6 @@ void vfree(const void *addr)
free((void *)addr);
}
void *krealloc(const void *ptr, size_t new_size, unsigned int flags)
{
(void)flags;
return realloc((void *)ptr, new_size);
}
static void redox_track_region(void *addr, size_t size, int fd)
{
struct redox_mapped_region *region = malloc(sizeof(*region));
@@ -330,9 +324,18 @@ void *redox_dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
void redox_dma_free_coherent(size_t size, void *vaddr, dma_addr_t dma_handle)
{
(void)size;
(void)dma_handle;
free(vaddr);
struct redox_mapped_region *region = redox_untrack_region(vaddr);
if (region) {
munmap(region->addr, region->size);
if (region->fd >= 0) {
close(region->fd);
}
free(region);
} else {
free(vaddr);
}
}
/*
@@ -400,13 +403,28 @@ void redox_pci_dev_put(struct pci_dev *pdev)
if (__sync_sub_and_fetch(&pdev->refcount, 1) == 0) {
redox_pci_release_regions(pdev);
free(pdev);
if (pdev != &g_pci_dev) {
free(pdev);
}
}
}
int redox_pci_enable_device(struct pci_dev *pdev)
{
return pdev ? 0 : -ENODEV;
if (!pdev) {
return -ENODEV;
}
if (pdev->enabled) {
return 0;
}
pdev->command |= (u16)(PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_MASTER);
pdev->enabled = true;
dev_info(&pdev->device_obj, "PCI device enabled (memory + I/O + bus master); "
"hardware command register was pre-configured by pcid-spawner\n");
return 0;
}
void redox_pci_set_master(struct pci_dev *pdev)
@@ -415,7 +433,8 @@ void redox_pci_set_master(struct pci_dev *pdev)
return;
}
pdev->command |= (u16)(1U << 2);
pdev->command |= (u16)PCI_COMMAND_MASTER;
dev_info(&pdev->device_obj, "PCI bus master enabled\n");
}
int redox_pci_request_regions(struct pci_dev *pdev, const char *name)
@@ -696,12 +715,12 @@ void mdelay(unsigned long msecs)
unsigned long msecs_to_jiffies(unsigned int msecs)
{
return (unsigned long)msecs;
return (unsigned long)msecs * HZ / 1000UL;
}
unsigned long usecs_to_jiffies(unsigned int usecs)
{
return (unsigned long)DIV_ROUND_UP(usecs, 1000U);
return DIV_ROUND_UP_ULL((unsigned long long)usecs * HZ, 1000000ULL);
}
struct redox_pm_state {
@@ -1178,7 +1197,7 @@ void redox_flush_scheduled_work(void)
unsigned long redox_wait_for_completion_timeout(struct completion *c, unsigned long timeout)
{
struct timespec abs_time;
unsigned long timeout_ms = timeout;
unsigned long timeout_ms = jiffies_to_msecs(timeout);
clock_gettime(CLOCK_REALTIME, &abs_time);
abs_time.tv_sec += timeout_ms / 1000U;
@@ -1191,7 +1210,7 @@ unsigned long redox_wait_for_completion_timeout(struct completion *c, unsigned l
pthread_mutex_lock(&c->mutex);
if (c->done) {
pthread_mutex_unlock(&c->mutex);
return timeout_ms > 0 ? timeout_ms : 1UL;
return timeout;
}
int rc = pthread_cond_timedwait(&c->cond, &c->mutex, &abs_time);