cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bootparam_utils.h (2907B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _ASM_X86_BOOTPARAM_UTILS_H
      3#define _ASM_X86_BOOTPARAM_UTILS_H
      4
      5#include <asm/bootparam.h>
      6
      7/*
      8 * This file is included from multiple environments.  Do not
      9 * add completing #includes to make it standalone.
     10 */
     11
     12/*
     13 * Deal with bootloaders which fail to initialize unknown fields in
     14 * boot_params to zero.  The list fields in this list are taken from
     15 * analysis of kexec-tools; if other broken bootloaders initialize a
     16 * different set of fields we will need to figure out how to disambiguate.
     17 *
     18 * Note: efi_info is commonly left uninitialized, but that field has a
     19 * private magic, so it is better to leave it unchanged.
     20 */
     21
     22#define sizeof_mbr(type, member) ({ sizeof(((type *)0)->member); })
     23
     24#define BOOT_PARAM_PRESERVE(struct_member)				\
     25	{								\
     26		.start = offsetof(struct boot_params, struct_member),	\
     27		.len   = sizeof_mbr(struct boot_params, struct_member),	\
     28	}
     29
     30struct boot_params_to_save {
     31	unsigned int start;
     32	unsigned int len;
     33};
     34
     35static void sanitize_boot_params(struct boot_params *boot_params)
     36{
     37	/* 
     38	 * IMPORTANT NOTE TO BOOTLOADER AUTHORS: do not simply clear
     39	 * this field.  The purpose of this field is to guarantee
     40	 * compliance with the x86 boot spec located in
     41	 * Documentation/x86/boot.rst .  That spec says that the
     42	 * *whole* structure should be cleared, after which only the
     43	 * portion defined by struct setup_header (boot_params->hdr)
     44	 * should be copied in.
     45	 *
     46	 * If you're having an issue because the sentinel is set, you
     47	 * need to change the whole structure to be cleared, not this
     48	 * (or any other) individual field, or you will soon have
     49	 * problems again.
     50	 */
     51	if (boot_params->sentinel) {
     52		static struct boot_params scratch;
     53		char *bp_base = (char *)boot_params;
     54		char *save_base = (char *)&scratch;
     55		int i;
     56
     57		const struct boot_params_to_save to_save[] = {
     58			BOOT_PARAM_PRESERVE(screen_info),
     59			BOOT_PARAM_PRESERVE(apm_bios_info),
     60			BOOT_PARAM_PRESERVE(tboot_addr),
     61			BOOT_PARAM_PRESERVE(ist_info),
     62			BOOT_PARAM_PRESERVE(hd0_info),
     63			BOOT_PARAM_PRESERVE(hd1_info),
     64			BOOT_PARAM_PRESERVE(sys_desc_table),
     65			BOOT_PARAM_PRESERVE(olpc_ofw_header),
     66			BOOT_PARAM_PRESERVE(efi_info),
     67			BOOT_PARAM_PRESERVE(alt_mem_k),
     68			BOOT_PARAM_PRESERVE(scratch),
     69			BOOT_PARAM_PRESERVE(e820_entries),
     70			BOOT_PARAM_PRESERVE(eddbuf_entries),
     71			BOOT_PARAM_PRESERVE(edd_mbr_sig_buf_entries),
     72			BOOT_PARAM_PRESERVE(edd_mbr_sig_buffer),
     73			BOOT_PARAM_PRESERVE(secure_boot),
     74			BOOT_PARAM_PRESERVE(hdr),
     75			BOOT_PARAM_PRESERVE(e820_table),
     76			BOOT_PARAM_PRESERVE(eddbuf),
     77			BOOT_PARAM_PRESERVE(cc_blob_address),
     78		};
     79
     80		memset(&scratch, 0, sizeof(scratch));
     81
     82		for (i = 0; i < ARRAY_SIZE(to_save); i++) {
     83			memcpy(save_base + to_save[i].start,
     84			       bp_base + to_save[i].start, to_save[i].len);
     85		}
     86
     87		memcpy(boot_params, save_base, sizeof(*boot_params));
     88	}
     89}
     90
     91#endif /* _ASM_X86_BOOTPARAM_UTILS_H */