Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/kernel/kcsan/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  encoding.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * KCSAN watchpoint encoding.
 *
 * Copyright (C) 2019, Google LLC.
 */


#ifndef _KERNEL_KCSAN_ENCODING_H
#define _KERNEL_KCSAN_ENCODING_H

#include <linux/bits.h>
#include <linux/log2.h>
#include <linux/mm.h>

#include "kcsan.h"

#define SLOT_RANGE PAGE_SIZE

#define INVALID_WATCHPOINT  0
#define CONSUMED_WATCHPOINT 1

/*
 * The maximum useful size of accesses for which we set up watchpoints is the
 * max range of slots we check on an access.
 */

#define MAX_ENCODABLE_SIZE (SLOT_RANGE * (1 + KCSAN_CHECK_ADJACENT))

/*
 * Number of bits we use to store size info.
 */

#define WATCHPOINT_SIZE_BITS bits_per(MAX_ENCODABLE_SIZE)
/*
 * This encoding for addresses discards the upper (1 for is-write + SIZE_BITS);
 * however, most 64-bit architectures do not use the full 64-bit address space.
 * Also, in order for a false positive to be observable 2 things need to happen:
 *
 * 1. different addresses but with the same encoded address race;
 * 2. and both map onto the same watchpoint slots;
 *
 * Both these are assumed to be very unlikely. However, in case it still
 * happens, the report logic will filter out the false positive (see report.c).
 */

#define WATCHPOINT_ADDR_BITS (BITS_PER_LONG-1 - WATCHPOINT_SIZE_BITS)

/* Bitmasks for the encoded watchpoint access information. */
#define WATCHPOINT_WRITE_MASK BIT(BITS_PER_LONG-1)
#define WATCHPOINT_SIZE_MASK GENMASK(BITS_PER_LONG-2, WATCHPOINT_ADDR_BITS)
#define WATCHPOINT_ADDR_MASK GENMASK(WATCHPOINT_ADDR_BITS-1, 0)
static_assert(WATCHPOINT_ADDR_MASK == (1UL << WATCHPOINT_ADDR_BITS) - 1);
static_assert((WATCHPOINT_WRITE_MASK ^ WATCHPOINT_SIZE_MASK ^ WATCHPOINT_ADDR_MASK) == ~0UL);

static inline bool check_encodable(unsigned long addr, size_t size)
{
 /*
 * While we can encode addrs<PAGE_SIZE, avoid crashing with a NULL
 * pointer deref inside KCSAN.
 */

 return addr >= PAGE_SIZE && size <= MAX_ENCODABLE_SIZE;
}

static inline long
encode_watchpoint(unsigned long addr, size_t size, bool is_write)
{
 return (long)((is_write ? WATCHPOINT_WRITE_MASK : 0) |
        (size << WATCHPOINT_ADDR_BITS) |
        (addr & WATCHPOINT_ADDR_MASK));
}

static __always_inline bool decode_watchpoint(long watchpoint,
           unsigned long *addr_masked,
           size_t *size,
           bool *is_write)
{
 if (watchpoint == INVALID_WATCHPOINT ||
     watchpoint == CONSUMED_WATCHPOINT)
  return false;

 *addr_masked =    (unsigned long)watchpoint & WATCHPOINT_ADDR_MASK;
 *size      =   ((unsigned long)watchpoint & WATCHPOINT_SIZE_MASK) >> WATCHPOINT_ADDR_BITS;
 *is_write    = !!((unsigned long)watchpoint & WATCHPOINT_WRITE_MASK);

 return true;
}

/*
 * Return watchpoint slot for an address.
 */

static __always_inline int watchpoint_slot(unsigned long addr)
{
 return (addr / PAGE_SIZE) % CONFIG_KCSAN_NUM_WATCHPOINTS;
}

static __always_inline bool matching_access(unsigned long addr1, size_t size1,
         unsigned long addr2, size_t size2)
{
 unsigned long end_range1 = addr1 + size1 - 1;
 unsigned long end_range2 = addr2 + size2 - 1;

 return addr1 <= end_range2 && addr2 <= end_range1;
}

#endif /* _KERNEL_KCSAN_ENCODING_H */

100%


¤ Dauer der Verarbeitung: 0.12 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 ist noch experimentell.