Skip to content

Commit 5ae74f2

Browse files
Lv Zhengrafaeljw
authored andcommitted
ACPI / tables: Move table override mechanisms to tables.c
This patch moves acpi_os_table_override() and acpi_os_physical_table_override() to tables.c. Along with the mechanisms, acpi_initrd_initialize_tables() is also moved to tables.c to form a static function. The following functions are renamed according to this change: 1. acpi_initrd_override() -> renamed to early_acpi_table_init(), which invokes acpi_table_initrd_init() 2. acpi_os_physical_table_override() -> which invokes acpi_table_initrd_override() 3. acpi_initialize_initrd_tables() -> renamed to acpi_table_initrd_scan() Signed-off-by: Lv Zheng <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent c3b46c7 commit 5ae74f2

File tree

5 files changed

+294
-285
lines changed

5 files changed

+294
-285
lines changed

arch/x86/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ void __init setup_arch(char **cmdline_p)
11391139
reserve_initrd();
11401140

11411141
#if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
1142-
acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start);
1142+
early_acpi_table_init((void *)initrd_start, initrd_end - initrd_start);
11431143
#endif
11441144

11451145
vsmp_init();

drivers/acpi/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
#define PREFIX "ACPI: "
2222

23-
void acpi_initrd_initialize_tables(void);
2423
acpi_status acpi_os_initialize1(void);
2524
void init_acpi_device_notify(void);
2625
int acpi_scan_init(void);

drivers/acpi/osl.c

Lines changed: 0 additions & 274 deletions
Original file line numberDiff line numberDiff line change
@@ -602,280 +602,6 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
602602
return AE_OK;
603603
}
604604

605-
static void acpi_table_taint(struct acpi_table_header *table)
606-
{
607-
pr_warn(PREFIX
608-
"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
609-
table->signature, table->oem_table_id);
610-
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
611-
}
612-
613-
#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
614-
#include <linux/earlycpio.h>
615-
#include <linux/memblock.h>
616-
617-
static u64 acpi_tables_addr;
618-
static int all_tables_size;
619-
620-
/* Copied from acpica/tbutils.c:acpi_tb_checksum() */
621-
static u8 __init acpi_table_checksum(u8 *buffer, u32 length)
622-
{
623-
u8 sum = 0;
624-
u8 *end = buffer + length;
625-
626-
while (buffer < end)
627-
sum = (u8) (sum + *(buffer++));
628-
return sum;
629-
}
630-
631-
/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */
632-
static const char * const table_sigs[] = {
633-
ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ,
634-
ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT,
635-
ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF,
636-
ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET,
637-
ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI,
638-
ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
639-
ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
640-
ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
641-
ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
642-
643-
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
644-
645-
#define ACPI_OVERRIDE_TABLES 64
646-
static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
647-
static DECLARE_BITMAP(acpi_initrd_installed, ACPI_OVERRIDE_TABLES);
648-
649-
#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
650-
651-
void __init acpi_initrd_override(void *data, size_t size)
652-
{
653-
int sig, no, table_nr = 0, total_offset = 0;
654-
long offset = 0;
655-
struct acpi_table_header *table;
656-
char cpio_path[32] = "kernel/firmware/acpi/";
657-
struct cpio_data file;
658-
659-
if (data == NULL || size == 0)
660-
return;
661-
662-
for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) {
663-
file = find_cpio_data(cpio_path, data, size, &offset);
664-
if (!file.data)
665-
break;
666-
667-
data += offset;
668-
size -= offset;
669-
670-
if (file.size < sizeof(struct acpi_table_header)) {
671-
pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n",
672-
cpio_path, file.name);
673-
continue;
674-
}
675-
676-
table = file.data;
677-
678-
for (sig = 0; table_sigs[sig]; sig++)
679-
if (!memcmp(table->signature, table_sigs[sig], 4))
680-
break;
681-
682-
if (!table_sigs[sig]) {
683-
pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n",
684-
cpio_path, file.name);
685-
continue;
686-
}
687-
if (file.size != table->length) {
688-
pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n",
689-
cpio_path, file.name);
690-
continue;
691-
}
692-
if (acpi_table_checksum(file.data, table->length)) {
693-
pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n",
694-
cpio_path, file.name);
695-
continue;
696-
}
697-
698-
pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n",
699-
table->signature, cpio_path, file.name, table->length);
700-
701-
all_tables_size += table->length;
702-
acpi_initrd_files[table_nr].data = file.data;
703-
acpi_initrd_files[table_nr].size = file.size;
704-
table_nr++;
705-
}
706-
if (table_nr == 0)
707-
return;
708-
709-
acpi_tables_addr =
710-
memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT,
711-
all_tables_size, PAGE_SIZE);
712-
if (!acpi_tables_addr) {
713-
WARN_ON(1);
714-
return;
715-
}
716-
/*
717-
* Only calling e820_add_reserve does not work and the
718-
* tables are invalid (memory got used) later.
719-
* memblock_reserve works as expected and the tables won't get modified.
720-
* But it's not enough on X86 because ioremap will
721-
* complain later (used by acpi_os_map_memory) that the pages
722-
* that should get mapped are not marked "reserved".
723-
* Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
724-
* works fine.
725-
*/
726-
memblock_reserve(acpi_tables_addr, all_tables_size);
727-
arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
728-
729-
/*
730-
* early_ioremap only can remap 256k one time. If we map all
731-
* tables one time, we will hit the limit. Need to map chunks
732-
* one by one during copying the same as that in relocate_initrd().
733-
*/
734-
for (no = 0; no < table_nr; no++) {
735-
unsigned char *src_p = acpi_initrd_files[no].data;
736-
phys_addr_t size = acpi_initrd_files[no].size;
737-
phys_addr_t dest_addr = acpi_tables_addr + total_offset;
738-
phys_addr_t slop, clen;
739-
char *dest_p;
740-
741-
total_offset += size;
742-
743-
while (size) {
744-
slop = dest_addr & ~PAGE_MASK;
745-
clen = size;
746-
if (clen > MAP_CHUNK_SIZE - slop)
747-
clen = MAP_CHUNK_SIZE - slop;
748-
dest_p = early_ioremap(dest_addr & PAGE_MASK,
749-
clen + slop);
750-
memcpy(dest_p + slop, src_p, clen);
751-
early_iounmap(dest_p, clen + slop);
752-
src_p += clen;
753-
dest_addr += clen;
754-
size -= clen;
755-
}
756-
}
757-
}
758-
759-
acpi_status
760-
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
761-
acpi_physical_address *address, u32 *length)
762-
{
763-
int table_offset = 0;
764-
int table_index = 0;
765-
struct acpi_table_header *table;
766-
u32 table_length;
767-
768-
*length = 0;
769-
*address = 0;
770-
if (!acpi_tables_addr)
771-
return AE_OK;
772-
773-
while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
774-
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
775-
ACPI_HEADER_SIZE);
776-
if (table_offset + table->length > all_tables_size) {
777-
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
778-
WARN_ON(1);
779-
return AE_OK;
780-
}
781-
782-
table_length = table->length;
783-
784-
/* Only override tables matched */
785-
if (test_bit(table_index, acpi_initrd_installed) ||
786-
memcmp(existing_table->signature, table->signature, 4) ||
787-
memcmp(table->oem_table_id, existing_table->oem_table_id,
788-
ACPI_OEM_TABLE_ID_SIZE)) {
789-
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
790-
goto next_table;
791-
}
792-
793-
*length = table_length;
794-
*address = acpi_tables_addr + table_offset;
795-
acpi_table_taint(existing_table);
796-
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
797-
set_bit(table_index, acpi_initrd_installed);
798-
break;
799-
800-
next_table:
801-
table_offset += table_length;
802-
table_index++;
803-
}
804-
return AE_OK;
805-
}
806-
807-
void __init acpi_initrd_initialize_tables(void)
808-
{
809-
int table_offset = 0;
810-
int table_index = 0;
811-
u32 table_length;
812-
struct acpi_table_header *table;
813-
814-
if (!acpi_tables_addr)
815-
return;
816-
817-
while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
818-
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
819-
ACPI_HEADER_SIZE);
820-
if (table_offset + table->length > all_tables_size) {
821-
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
822-
WARN_ON(1);
823-
return;
824-
}
825-
826-
table_length = table->length;
827-
828-
/* Skip RSDT/XSDT which should only be used for override */
829-
if (test_bit(table_index, acpi_initrd_installed) ||
830-
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) ||
831-
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) {
832-
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
833-
goto next_table;
834-
}
835-
836-
acpi_table_taint(table);
837-
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
838-
acpi_install_table(acpi_tables_addr + table_offset, TRUE);
839-
set_bit(table_index, acpi_initrd_installed);
840-
next_table:
841-
table_offset += table_length;
842-
table_index++;
843-
}
844-
}
845-
#else
846-
acpi_status
847-
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
848-
acpi_physical_address *address,
849-
u32 *table_length)
850-
{
851-
*table_length = 0;
852-
*address = 0;
853-
return AE_OK;
854-
}
855-
856-
void __init acpi_initrd_initialize_tables(void)
857-
{
858-
}
859-
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
860-
861-
acpi_status
862-
acpi_os_table_override(struct acpi_table_header *existing_table,
863-
struct acpi_table_header **new_table)
864-
{
865-
if (!existing_table || !new_table)
866-
return AE_BAD_PARAMETER;
867-
868-
*new_table = NULL;
869-
870-
#ifdef CONFIG_ACPI_CUSTOM_DSDT
871-
if (strncmp(existing_table->signature, "DSDT", 4) == 0)
872-
*new_table = (struct acpi_table_header *)AmlCode;
873-
#endif
874-
if (*new_table != NULL)
875-
acpi_table_taint(existing_table);
876-
return AE_OK;
877-
}
878-
879605
static irqreturn_t acpi_irq(int irq, void *dev_id)
880606
{
881607
u32 handled;

0 commit comments

Comments
 (0)