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

misc.c (4840B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) International Business Machines Corp., 2006
      4 *
      5 * Author: Artem Bityutskiy (Битюцкий Артём)
      6 */
      7
      8/* Here we keep miscellaneous functions which are used all over the UBI code */
      9
     10#include "ubi.h"
     11
     12/**
     13 * calc_data_len - calculate how much real data is stored in a buffer.
     14 * @ubi: UBI device description object
     15 * @buf: a buffer with the contents of the physical eraseblock
     16 * @length: the buffer length
     17 *
     18 * This function calculates how much "real data" is stored in @buf and returnes
     19 * the length. Continuous 0xFF bytes at the end of the buffer are not
     20 * considered as "real data".
     21 */
     22int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
     23		      int length)
     24{
     25	int i;
     26
     27	ubi_assert(!(length & (ubi->min_io_size - 1)));
     28
     29	for (i = length - 1; i >= 0; i--)
     30		if (((const uint8_t *)buf)[i] != 0xFF)
     31			break;
     32
     33	/* The resulting length must be aligned to the minimum flash I/O size */
     34	length = ALIGN(i + 1, ubi->min_io_size);
     35	return length;
     36}
     37
     38/**
     39 * ubi_check_volume - check the contents of a static volume.
     40 * @ubi: UBI device description object
     41 * @vol_id: ID of the volume to check
     42 *
     43 * This function checks if static volume @vol_id is corrupted by fully reading
     44 * it and checking data CRC. This function returns %0 if the volume is not
     45 * corrupted, %1 if it is corrupted and a negative error code in case of
     46 * failure. Dynamic volumes are not checked and zero is returned immediately.
     47 */
     48int ubi_check_volume(struct ubi_device *ubi, int vol_id)
     49{
     50	void *buf;
     51	int err = 0, i;
     52	struct ubi_volume *vol = ubi->volumes[vol_id];
     53
     54	if (vol->vol_type != UBI_STATIC_VOLUME)
     55		return 0;
     56
     57	buf = vmalloc(vol->usable_leb_size);
     58	if (!buf)
     59		return -ENOMEM;
     60
     61	for (i = 0; i < vol->used_ebs; i++) {
     62		int size;
     63
     64		cond_resched();
     65
     66		if (i == vol->used_ebs - 1)
     67			size = vol->last_eb_bytes;
     68		else
     69			size = vol->usable_leb_size;
     70
     71		err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1);
     72		if (err) {
     73			if (mtd_is_eccerr(err))
     74				err = 1;
     75			break;
     76		}
     77	}
     78
     79	vfree(buf);
     80	return err;
     81}
     82
     83/**
     84 * ubi_update_reserved - update bad eraseblock handling accounting data.
     85 * @ubi: UBI device description object
     86 *
     87 * This function calculates the gap between current number of PEBs reserved for
     88 * bad eraseblock handling and the required level of PEBs that must be
     89 * reserved, and if necessary, reserves more PEBs to fill that gap, according
     90 * to availability. Should be called with ubi->volumes_lock held.
     91 */
     92void ubi_update_reserved(struct ubi_device *ubi)
     93{
     94	int need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs;
     95
     96	if (need <= 0 || ubi->avail_pebs == 0)
     97		return;
     98
     99	need = min_t(int, need, ubi->avail_pebs);
    100	ubi->avail_pebs -= need;
    101	ubi->rsvd_pebs += need;
    102	ubi->beb_rsvd_pebs += need;
    103	ubi_msg(ubi, "reserved more %d PEBs for bad PEB handling", need);
    104}
    105
    106/**
    107 * ubi_calculate_reserved - calculate how many PEBs must be reserved for bad
    108 * eraseblock handling.
    109 * @ubi: UBI device description object
    110 */
    111void ubi_calculate_reserved(struct ubi_device *ubi)
    112{
    113	/*
    114	 * Calculate the actual number of PEBs currently needed to be reserved
    115	 * for future bad eraseblock handling.
    116	 */
    117	ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count;
    118	if (ubi->beb_rsvd_level < 0) {
    119		ubi->beb_rsvd_level = 0;
    120		ubi_warn(ubi, "number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)",
    121			 ubi->bad_peb_count, ubi->bad_peb_limit);
    122	}
    123}
    124
    125/**
    126 * ubi_check_pattern - check if buffer contains only a certain byte pattern.
    127 * @buf: buffer to check
    128 * @patt: the pattern to check
    129 * @size: buffer size in bytes
    130 *
    131 * This function returns %1 in there are only @patt bytes in @buf, and %0 if
    132 * something else was also found.
    133 */
    134int ubi_check_pattern(const void *buf, uint8_t patt, int size)
    135{
    136	int i;
    137
    138	for (i = 0; i < size; i++)
    139		if (((const uint8_t *)buf)[i] != patt)
    140			return 0;
    141	return 1;
    142}
    143
    144/* Normal UBI messages */
    145void ubi_msg(const struct ubi_device *ubi, const char *fmt, ...)
    146{
    147	struct va_format vaf;
    148	va_list args;
    149
    150	va_start(args, fmt);
    151
    152	vaf.fmt = fmt;
    153	vaf.va = &args;
    154
    155	pr_notice(UBI_NAME_STR "%d: %pV\n", ubi->ubi_num, &vaf);
    156
    157	va_end(args);
    158}
    159
    160/* UBI warning messages */
    161void ubi_warn(const struct ubi_device *ubi, const char *fmt, ...)
    162{
    163	struct va_format vaf;
    164	va_list args;
    165
    166	va_start(args, fmt);
    167
    168	vaf.fmt = fmt;
    169	vaf.va = &args;
    170
    171	pr_warn(UBI_NAME_STR "%d warning: %ps: %pV\n",
    172		ubi->ubi_num, __builtin_return_address(0), &vaf);
    173
    174	va_end(args);
    175}
    176
    177/* UBI error messages */
    178void ubi_err(const struct ubi_device *ubi, const char *fmt, ...)
    179{
    180	struct va_format vaf;
    181	va_list args;
    182
    183	va_start(args, fmt);
    184
    185	vaf.fmt = fmt;
    186	vaf.va = &args;
    187
    188	pr_err(UBI_NAME_STR "%d error: %ps: %pV\n",
    189	       ubi->ubi_num, __builtin_return_address(0), &vaf);
    190	va_end(args);
    191}