Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
# SPDX-License-Identifier: GPL-2.0
# This file was copied from arm64/kernel/pi/Makefile.
KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \
-Os -DDISABLE_BRANCH_PROFILING $(DISABLE_KSTACK_ERASE) \
$(call cc-option,-mbranch-protection=none) \
-I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \
-include $(srctree)/include/linux/hidden.h \
-D__DISABLE_EXPORTS -ffreestanding \
-fno-asynchronous-unwind-tables -fno-unwind-tables \
$(call cc-option,-fno-addrsig)
# Disable LTO
KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
KBUILD_CFLAGS += -mcmodel=medany
CFLAGS_cmdline_early.o += -D__NO_FORTIFY
CFLAGS_fdt_early.o += -D__NO_FORTIFY
# lib/string.c already defines __NO_FORTIFY
CFLAGS_ctype.o += -D__NO_FORTIFY
CFLAGS_lib-fdt.o += -D__NO_FORTIFY
CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
CFLAGS_archrandom_early.o += -D__NO_FORTIFY
$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
--remove-section=.note.gnu.property \
--prefix-alloc-sections=.init.pi
$(obj)/%.pi.o: $(obj)/%.o FORCE
$(call if_changed,objcopy)
$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
$(call if_changed_rule,cc_o_c)
$(obj)/string.o: $(srctree)/lib/string.c FORCE
$(call if_changed_rule,cc_o_c)
$(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
$(call if_changed_rule,cc_o_c)
obj-y := cmdline_early.pi.o fdt_early.pi.o string.pi.o ctype.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o archrandom_early.pi.o
targets := $(patsubst %.pi.o,%.o,$(obj-y))
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <asm/csr.h>
#include <linux/processor.h>
#include "pi.h"
/*
* To avoid rewriting code include asm/archrandom.h and create macros
* for the functions that won't be included.
*/
#undef riscv_has_extension_unlikely
#define riscv_has_extension_likely(...) false
#undef pr_err_once
#define pr_err_once(...)
#include <asm/archrandom.h>
u64 get_kaslr_seed_zkr(const uintptr_t dtb_pa)
{
unsigned long seed = 0;
if (!fdt_early_match_extension_isa((const void *)dtb_pa, "zkr"))
return 0;
if (!csr_seed_long(&seed))
return 0;
return seed;
}
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/types.h>
#include <linux/init.h>
#include <linux/libfdt.h>
#include <linux/string.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
#include "pi.h"
static char early_cmdline[COMMAND_LINE_SIZE];
static char *get_early_cmdline(uintptr_t dtb_pa)
{
const char *fdt_cmdline;
ssize_t fdt_cmdline_size = 0;
int chosen_node;
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
chosen_node = fdt_path_offset((void *)dtb_pa, "/chosen");
if (chosen_node >= 0) {
fdt_cmdline = fdt_getprop((void *)dtb_pa, chosen_node,
"bootargs", NULL);
if (fdt_cmdline) {
fdt_cmdline_size = strscpy(early_cmdline, fdt_cmdline);
if (fdt_cmdline_size < 0)
return early_cmdline;
}
}
}
if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */)
strscpy(early_cmdline + fdt_cmdline_size, CONFIG_CMDLINE,
COMMAND_LINE_SIZE - fdt_cmdline_size);
return early_cmdline;
}
static u64 match_noXlvl(char *cmdline)
{
if (strstr(cmdline, "no4lvl"))
return SATP_MODE_39;
else if (strstr(cmdline, "no5lvl"))
return SATP_MODE_48;
return 0;
}
u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa)
{
char *cmdline = get_early_cmdline(dtb_pa);
return match_noXlvl(cmdline);
}
static bool match_nokaslr(char *cmdline)
{
return strstr(cmdline, "nokaslr");
}
bool set_nokaslr_from_cmdline(uintptr_t dtb_pa)
{
char *cmdline = get_early_cmdline(dtb_pa);
return match_nokaslr(cmdline);
}
@@ -0,0 +1,225 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/types.h>
#include <linux/init.h>
#include <linux/libfdt.h>
#include <linux/ctype.h>
#include <asm/csr.h>
#include "pi.h"
u64 get_kaslr_seed(uintptr_t dtb_pa)
{
int node, len;
fdt64_t *prop;
u64 ret;
node = fdt_path_offset((void *)dtb_pa, "/chosen");
if (node < 0)
return 0;
prop = fdt_getprop_w((void *)dtb_pa, node, "kaslr-seed", &len);
if (!prop || len != sizeof(u64))
return 0;
ret = fdt64_to_cpu(*prop);
*prop = 0;
return ret;
}
/**
* fdt_device_is_available - check if a device is available for use
*
* @fdt: pointer to the device tree blob
* @node: offset of the node whose property to find
*
* Returns true if the status property is absent or set to "okay" or "ok",
* false otherwise
*/
static bool fdt_device_is_available(const void *fdt, int node)
{
const char *status;
int statlen;
status = fdt_getprop(fdt, node, "status", &statlen);
if (!status)
return true;
if (statlen > 0) {
if (!strcmp(status, "okay") || !strcmp(status, "ok"))
return true;
}
return false;
}
/* Copy of fdt_nodename_eq_ */
static int fdt_node_name_eq(const void *fdt, int offset,
const char *s)
{
int olen;
int len = strlen(s);
const char *p = fdt_get_name(fdt, offset, &olen);
if (!p || olen < len)
/* short match */
return 0;
if (memcmp(p, s, len) != 0)
return 0;
if (p[len] == '\0')
return 1;
else if (!memchr(s, '@', len) && (p[len] == '@'))
return 1;
else
return 0;
}
/**
* isa_string_contains - check if isa string contains an extension
*
* @isa_str: isa string to search
* @ext_name: the extension to search for
*
* Returns true if the extension is in the given isa string,
* false otherwise
*/
static bool isa_string_contains(const char *isa_str, const char *ext_name)
{
size_t i, single_end, len = strlen(ext_name);
char ext_end;
/* Error must contain rv32/64 */
if (strlen(isa_str) < 4)
return false;
if (len == 1) {
single_end = strcspn(isa_str, "sSxXzZ");
/* Search for single chars between rv32/64 and multi-letter extensions */
for (i = 4; i < single_end; i++) {
if (tolower(isa_str[i]) == ext_name[0])
return true;
}
return false;
}
/* Skip to start of multi-letter extensions */
isa_str = strpbrk(isa_str, "sSxXzZ");
while (isa_str) {
if (strncasecmp(isa_str, ext_name, len) == 0) {
ext_end = isa_str[len];
/* Check if matches the whole extension. */
if (ext_end == '\0' || ext_end == '_')
return true;
}
/* Multi-letter extensions must be split from other multi-letter
* extensions with an "_", the end of a multi-letter extension will
* either be the null character or the "_" at the start of the next
* multi-letter extension.
*/
isa_str = strchr(isa_str, '_');
if (isa_str)
isa_str++;
}
return false;
}
/**
* early_cpu_isa_ext_available - check if cpu node has an extension
*
* @fdt: pointer to the device tree blob
* @node: offset of the cpu node
* @ext_name: the extension to search for
*
* Returns true if the cpu node has the extension,
* false otherwise
*/
static bool early_cpu_isa_ext_available(const void *fdt, int node, const char *ext_name)
{
const void *prop;
int len;
prop = fdt_getprop(fdt, node, "riscv,isa-extensions", &len);
if (prop && fdt_stringlist_contains(prop, len, ext_name))
return true;
prop = fdt_getprop(fdt, node, "riscv,isa", &len);
if (prop && isa_string_contains(prop, ext_name))
return true;
return false;
}
/**
* fdt_early_match_extension_isa - check if all cpu nodes have an extension
*
* @fdt: pointer to the device tree blob
* @ext_name: the extension to search for
*
* Returns true if the all available the cpu nodes have the extension,
* false otherwise
*/
bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name)
{
int node, parent;
bool ret = false;
parent = fdt_path_offset(fdt, "/cpus");
if (parent < 0)
return false;
fdt_for_each_subnode(node, fdt, parent) {
if (!fdt_node_name_eq(fdt, node, "cpu"))
continue;
if (!fdt_device_is_available(fdt, node))
continue;
if (!early_cpu_isa_ext_available(fdt, node, ext_name))
return false;
ret = true;
}
return ret;
}
/**
* set_satp_mode_from_fdt - determine SATP mode based on the MMU type in fdt
*
* @dtb_pa: physical address of the device tree blob
*
* Returns the SATP mode corresponding to the MMU type of the first enabled CPU,
* 0 otherwise
*/
u64 set_satp_mode_from_fdt(uintptr_t dtb_pa)
{
const void *fdt = (const void *)dtb_pa;
const char *mmu_type;
int node, parent;
parent = fdt_path_offset(fdt, "/cpus");
if (parent < 0)
return 0;
fdt_for_each_subnode(node, fdt, parent) {
if (!fdt_node_name_eq(fdt, node, "cpu"))
continue;
if (!fdt_device_is_available(fdt, node))
continue;
mmu_type = fdt_getprop(fdt, node, "mmu-type", NULL);
if (!mmu_type)
break;
if (!strcmp(mmu_type, "riscv,sv39"))
return SATP_MODE_39;
else if (!strcmp(mmu_type, "riscv,sv48"))
return SATP_MODE_48;
break;
}
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _RISCV_PI_H_
#define _RISCV_PI_H_
#include <linux/types.h>
/*
* The following functions are exported (but prefixed). Declare them here so
* that LLVM does not complain it lacks the 'static' keyword (which, if
* added, makes LLVM complain because the function is unused).
*/
u64 get_kaslr_seed(uintptr_t dtb_pa);
u64 get_kaslr_seed_zkr(const uintptr_t dtb_pa);
bool set_nokaslr_from_cmdline(uintptr_t dtb_pa);
u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa);
u64 set_satp_mode_from_fdt(uintptr_t dtb_pa);
bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name);
#endif /* _RISCV_PI_H_ */