Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  adf_mstate_mgr.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2024 Intel Corporation */

#include <linux/slab.h>
#include <linux/types.h>
#include "adf_mstate_mgr.h"

#define ADF_MSTATE_MAGIC 0xADF5CAEA
#define ADF_MSTATE_VERSION 0x1

struct adf_mstate_sect_h {
 u8 id[ADF_MSTATE_ID_LEN];
 u32 size;
 u32 sub_sects;
 u8 state[];
};

u32 adf_mstate_state_size(struct adf_mstate_mgr *mgr)
{
 return mgr->state - mgr->buf;
}

static inline u32 adf_mstate_avail_room(struct adf_mstate_mgr *mgr)
{
 return mgr->buf + mgr->size - mgr->state;
}

void adf_mstate_mgr_init(struct adf_mstate_mgr *mgr, u8 *buf, u32 size)
{
 mgr->buf = buf;
 mgr->state = buf;
 mgr->size = size;
 mgr->n_sects = 0;
};

struct adf_mstate_mgr *adf_mstate_mgr_new(u8 *buf, u32 size)
{
 struct adf_mstate_mgr *mgr;

 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
 if (!mgr)
  return NULL;

 adf_mstate_mgr_init(mgr, buf, size);

 return mgr;
}

void adf_mstate_mgr_destroy(struct adf_mstate_mgr *mgr)
{
 kfree(mgr);
}

void adf_mstate_mgr_init_from_parent(struct adf_mstate_mgr *mgr,
         struct adf_mstate_mgr *p_mgr)
{
 adf_mstate_mgr_init(mgr, p_mgr->state,
       p_mgr->size - adf_mstate_state_size(p_mgr));
}

void adf_mstate_mgr_init_from_psect(struct adf_mstate_mgr *mgr,
        struct adf_mstate_sect_h *p_sect)
{
 adf_mstate_mgr_init(mgr, p_sect->state, p_sect->size);
 mgr->n_sects = p_sect->sub_sects;
}

static void adf_mstate_preamble_init(struct adf_mstate_preh *preamble)
{
 preamble->magic = ADF_MSTATE_MAGIC;
 preamble->version = ADF_MSTATE_VERSION;
 preamble->preh_len = sizeof(*preamble);
 preamble->size = 0;
 preamble->n_sects = 0;
}

/* default preambles checker */
static int adf_mstate_preamble_def_checker(struct adf_mstate_preh *preamble,
        void *opaque)
{
 struct adf_mstate_mgr *mgr = opaque;

 if (preamble->magic != ADF_MSTATE_MAGIC ||
     preamble->version > ADF_MSTATE_VERSION ||
     preamble->preh_len > mgr->size) {
  pr_debug("QAT: LM - Invalid state (magic=%#x, version=%#x, hlen=%u), state_size=%u\n",
    preamble->magic, preamble->version, preamble->preh_len,
    mgr->size);
  return -EINVAL;
 }

 return 0;
}

struct adf_mstate_preh *adf_mstate_preamble_add(struct adf_mstate_mgr *mgr)
{
 struct adf_mstate_preh *pre = (struct adf_mstate_preh *)mgr->buf;

 if (adf_mstate_avail_room(mgr) < sizeof(*pre)) {
  pr_err("QAT: LM - Not enough space for preamble\n");
  return NULL;
 }

 adf_mstate_preamble_init(pre);
 mgr->state += pre->preh_len;

 return pre;
}

int adf_mstate_preamble_update(struct adf_mstate_mgr *mgr)
{
 struct adf_mstate_preh *preamble = (struct adf_mstate_preh *)mgr->buf;

 preamble->size = adf_mstate_state_size(mgr) - preamble->preh_len;
 preamble->n_sects = mgr->n_sects;

 return 0;
}

static void adf_mstate_dump_sect(struct adf_mstate_sect_h *sect,
     const char *prefix)
{
 pr_debug("QAT: LM - %s QAT state section %s\n", prefix, sect->id);
 print_hex_dump_debug("h-", DUMP_PREFIX_OFFSET, 16, 2, sect,
        sizeof(*sect), true);
 print_hex_dump_debug("s-", DUMP_PREFIX_OFFSET, 16, 2, sect->state,
        sect->size, true);
}

static inline void __adf_mstate_sect_update(struct adf_mstate_mgr *mgr,
         struct adf_mstate_sect_h *sect,
         u32 size,
         u32 n_subsects)
{
 sect->size += size;
 sect->sub_sects += n_subsects;
 mgr->n_sects++;
 mgr->state += sect->size;

 adf_mstate_dump_sect(sect, "Add");
}

void adf_mstate_sect_update(struct adf_mstate_mgr *p_mgr,
       struct adf_mstate_mgr *curr_mgr,
       struct adf_mstate_sect_h *sect)
{
 __adf_mstate_sect_update(p_mgr, sect, adf_mstate_state_size(curr_mgr),
     curr_mgr->n_sects);
}

static struct adf_mstate_sect_h *adf_mstate_sect_add_header(struct adf_mstate_mgr *mgr,
           const char *id)
{
 struct adf_mstate_sect_h *sect = (struct adf_mstate_sect_h *)(mgr->state);

 if (adf_mstate_avail_room(mgr) < sizeof(*sect)) {
  pr_debug("QAT: LM - Not enough space for header of QAT state sect %s\n", id);
  return NULL;
 }

 strscpy(sect->id, id, sizeof(sect->id));
 sect->size = 0;
 sect->sub_sects = 0;
 mgr->state += sizeof(*sect);

 return sect;
}

struct adf_mstate_sect_h *adf_mstate_sect_add_vreg(struct adf_mstate_mgr *mgr,
         const char *id,
         struct adf_mstate_vreginfo *info)
{
 struct adf_mstate_sect_h *sect;

 sect = adf_mstate_sect_add_header(mgr, id);
 if (!sect)
  return NULL;

 if (adf_mstate_avail_room(mgr) < info->size) {
  pr_debug("QAT: LM - Not enough space for QAT state sect %s, requires %u\n",
    id, info->size);
  return NULL;
 }

 memcpy(sect->state, info->addr, info->size);
 __adf_mstate_sect_update(mgr, sect, info->size, 0);

 return sect;
}

struct adf_mstate_sect_h *adf_mstate_sect_add(struct adf_mstate_mgr *mgr,
           const char *id,
           adf_mstate_populate populate,
           void *opaque)
{
 struct adf_mstate_mgr sub_sects_mgr;
 struct adf_mstate_sect_h *sect;
 int avail_room, size;

 sect = adf_mstate_sect_add_header(mgr, id);
 if (!sect)
  return NULL;

 if (!populate)
  return sect;

 avail_room = adf_mstate_avail_room(mgr);
 adf_mstate_mgr_init_from_parent(&sub_sects_mgr, mgr);

 size = (*populate)(&sub_sects_mgr, sect->state, avail_room, opaque);
 if (size < 0)
  return NULL;

 size += adf_mstate_state_size(&sub_sects_mgr);
 if (avail_room < size) {
  pr_debug("QAT: LM - Not enough space for QAT state sect %s, requires %u\n",
    id, size);
  return NULL;
 }
 __adf_mstate_sect_update(mgr, sect, size, sub_sects_mgr.n_sects);

 return sect;
}

static int adf_mstate_sect_validate(struct adf_mstate_mgr *mgr)
{
 struct adf_mstate_sect_h *start = (struct adf_mstate_sect_h *)mgr->state;
 struct adf_mstate_sect_h *sect = start;
 u64 end;
 int i;

 end = (uintptr_t)mgr->buf + mgr->size;
 for (i = 0; i < mgr->n_sects; i++) {
  uintptr_t s_start = (uintptr_t)sect->state;
  uintptr_t s_end = s_start + sect->size;

  if (s_end < s_start || s_end > end) {
   pr_debug("QAT: LM - Corrupted state section (index=%u, size=%u) in state_mgr (size=%u, secs=%u)\n",
     i, sect->size, mgr->size, mgr->n_sects);
   return -EINVAL;
  }
  sect = (struct adf_mstate_sect_h *)s_end;
 }

 pr_debug("QAT: LM - Scanned section (last child=%s, size=%lu) in state_mgr (size=%u, secs=%u)\n",
   start->id, sizeof(struct adf_mstate_sect_h) * (ulong)(sect - start),
   mgr->size, mgr->n_sects);

 return 0;
}

u32 adf_mstate_state_size_from_remote(struct adf_mstate_mgr *mgr)
{
 struct adf_mstate_preh *preh = (struct adf_mstate_preh *)mgr->buf;

 return preh->preh_len + preh->size;
}

int adf_mstate_mgr_init_from_remote(struct adf_mstate_mgr *mgr, u8 *buf, u32 size,
        adf_mstate_preamble_checker pre_checker,
        void *opaque)
{
 struct adf_mstate_preh *pre;
 int ret;

 adf_mstate_mgr_init(mgr, buf, size);
 pre = (struct adf_mstate_preh *)(mgr->buf);

 pr_debug("QAT: LM - Dump state preambles\n");
 print_hex_dump_debug("", DUMP_PREFIX_OFFSET, 16, 2, pre, pre->preh_len, 0);

 if (pre_checker)
  ret = (*pre_checker)(pre, opaque);
 else
  ret = adf_mstate_preamble_def_checker(pre, mgr);
 if (ret)
  return ret;

 mgr->state = mgr->buf + pre->preh_len;
 mgr->n_sects = pre->n_sects;

 return adf_mstate_sect_validate(mgr);
}

struct adf_mstate_sect_h *adf_mstate_sect_lookup(struct adf_mstate_mgr *mgr,
       const char *id,
       adf_mstate_action action,
       void *opaque)
{
 struct adf_mstate_sect_h *sect = (struct adf_mstate_sect_h *)mgr->state;
 struct adf_mstate_mgr sub_sects_mgr;
 int i, ret;

 for (i = 0; i < mgr->n_sects; i++) {
  if (!strncmp(sect->id, id, sizeof(sect->id)))
   goto found;

  sect = (struct adf_mstate_sect_h *)(sect->state + sect->size);
 }

 return NULL;

found:
 adf_mstate_dump_sect(sect, "Found");

 adf_mstate_mgr_init_from_psect(&sub_sects_mgr, sect);
 if (sect->sub_sects && adf_mstate_sect_validate(&sub_sects_mgr))
  return NULL;

 if (!action)
  return sect;

 ret = (*action)(&sub_sects_mgr, sect->state, sect->size, opaque);
 if (ret)
  return NULL;

 return sect;
}

Messung V0.5
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.11 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge