Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/arch/s390/boot/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  ipl_report.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
#include <linux/ctype.h>
#include <asm/ebcdic.h>
#include <asm/sclp.h>
#include <asm/sections.h>
#include <asm/boot_data.h>
#include <asm/physmem_info.h>
#include <uapi/asm/ipl.h>
#include "boot.h"

int __bootdata_preserved(ipl_secure_flag);

unsigned long __bootdata_preserved(ipl_cert_list_addr);
unsigned long __bootdata_preserved(ipl_cert_list_size);

unsigned long __bootdata(early_ipl_comp_list_addr);
unsigned long __bootdata(early_ipl_comp_list_size);

static struct ipl_rb_certificates *certs;
static struct ipl_rb_components *comps;
static bool ipl_report_needs_saving;

#define for_each_rb_entry(entry, rb) \
 for (entry = rb->entries; \
      (void *) entry + sizeof(*entry) <= (void *) rb + rb->len; \
      entry++)

static unsigned long get_cert_comp_list_size(void)
{
 struct ipl_rb_certificate_entry *cert;
 struct ipl_rb_component_entry *comp;

 /*
 * Find the length for the IPL report boot data
 */

 early_ipl_comp_list_size = 0;
 for_each_rb_entry(comp, comps)
  early_ipl_comp_list_size += sizeof(*comp);
 ipl_cert_list_size = 0;
 for_each_rb_entry(cert, certs)
  ipl_cert_list_size += sizeof(unsigned int) + cert->len;
 return ipl_cert_list_size + early_ipl_comp_list_size;
}

bool ipl_report_certs_intersects(unsigned long addr, unsigned long size,
     unsigned long *intersection_start)
{
 struct ipl_rb_certificate_entry *cert;

 if (!ipl_report_needs_saving)
  return false;

 for_each_rb_entry(cert, certs) {
  if (intersects(addr, size, cert->addr, cert->len)) {
   *intersection_start = cert->addr;
   return true;
  }
 }
 return false;
}

static void copy_components_bootdata(void)
{
 struct ipl_rb_component_entry *comp, *ptr;

 ptr = (struct ipl_rb_component_entry *) early_ipl_comp_list_addr;
 for_each_rb_entry(comp, comps)
  memcpy(ptr++, comp, sizeof(*ptr));
}

static void copy_certificates_bootdata(void)
{
 struct ipl_rb_certificate_entry *cert;
 void *ptr;

 ptr = (void *) ipl_cert_list_addr;
 for_each_rb_entry(cert, certs) {
  *(unsigned int *) ptr = cert->len;
  ptr += sizeof(unsigned int);
  memcpy(ptr, (void *) cert->addr, cert->len);
  ptr += cert->len;
 }
}

int read_ipl_report(void)
{
 struct ipl_pl_hdr *pl_hdr;
 struct ipl_rl_hdr *rl_hdr;
 struct ipl_rb_hdr *rb_hdr;
 unsigned long tmp;
 void *rl_end;

 /*
 * Check if there is a IPL report by looking at the copy
 * of the IPL parameter information block.
 */

 if (!ipl_block_valid ||
     !(ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR))
  return -1;
 ipl_secure_flag = !!(ipl_block.hdr.flags & IPL_PL_FLAG_SIPL);
 /*
 * There is an IPL report, to find it load the pointer to the
 * IPL parameter information block from lowcore and skip past
 * the IPL parameter list, then align the address to a double
 * word boundary.
 */

 tmp = (unsigned long)get_lowcore()->ipl_parmblock_ptr;
 pl_hdr = (struct ipl_pl_hdr *) tmp;
 tmp = (tmp + pl_hdr->len + 7) & -8UL;
 rl_hdr = (struct ipl_rl_hdr *) tmp;
 /* Walk through the IPL report blocks in the IPL Report list */
 certs = NULL;
 comps = NULL;
 rl_end = (void *) rl_hdr + rl_hdr->len;
 rb_hdr = (void *) rl_hdr + sizeof(*rl_hdr);
 while ((void *) rb_hdr + sizeof(*rb_hdr) < rl_end &&
        (void *) rb_hdr + rb_hdr->len <= rl_end) {

  switch (rb_hdr->rbt) {
  case IPL_RBT_CERTIFICATES:
   certs = (struct ipl_rb_certificates *) rb_hdr;
   break;
  case IPL_RBT_COMPONENTS:
   comps = (struct ipl_rb_components *) rb_hdr;
   break;
  default:
   break;
  }

  rb_hdr = (void *) rb_hdr + rb_hdr->len;
 }

 /*
 * With either the component list or the certificate list
 * missing the kernel will stay ignorant of secure IPL.
 */

 if (!comps || !certs) {
  certs = NULL;
  return -1;
 }

 ipl_report_needs_saving = true;
 physmem_reserve(RR_IPLREPORT, (unsigned long)pl_hdr,
   (unsigned long)rl_end - (unsigned long)pl_hdr);
 return 0;
}

void save_ipl_cert_comp_list(void)
{
 unsigned long size;

 if (!ipl_report_needs_saving)
  return;

 size = get_cert_comp_list_size();
 early_ipl_comp_list_addr = physmem_alloc_or_die(RR_CERT_COMP_LIST, size, sizeof(int));
 ipl_cert_list_addr = early_ipl_comp_list_addr + early_ipl_comp_list_size;

 copy_components_bootdata();
 copy_certificates_bootdata();
 physmem_free(RR_IPLREPORT);
 ipl_report_needs_saving = false;
}

Messung V0.5
C=97 H=87 G=91

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.