forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch kvm-arm64/selftest/s2-faults into kvmarm-master/next
* kvm-arm64/selftest/s2-faults: : . : New KVM/arm64 selftests exercising various sorts of S2 faults, courtesy : of Ricardo Koller. From the cover letter: : : "This series adds a new aarch64 selftest for testing stage 2 fault handling : for various combinations of guest accesses (e.g., write, S1PTW), backing : sources (e.g., anon), and types of faults (e.g., read on hugetlbfs with a : hole, write on a readonly memslot). Each test tries a different combination : and then checks that the access results in the right behavior (e.g., uffd : faults with the right address and write/read flag). [...]" : . KVM: selftests: aarch64: Add mix of tests into page_fault_test KVM: selftests: aarch64: Add readonly memslot tests into page_fault_test KVM: selftests: aarch64: Add dirty logging tests into page_fault_test KVM: selftests: aarch64: Add userfaultfd tests into page_fault_test KVM: selftests: aarch64: Add aarch64/page_fault_test KVM: selftests: Use the right memslot for code, page-tables, and data allocations KVM: selftests: Fix alignment in virt_arch_pgd_alloc() and vm_vaddr_alloc() KVM: selftests: Add vm->memslots[] and enum kvm_mem_region_type KVM: selftests: Stash backing_src_type in struct userspace_mem_region tools: Copy bitfield.h from the kernel sources KVM: selftests: aarch64: Construct DEFAULT_MAIR_EL1 using sysreg.h macros KVM: selftests: Add missing close and munmap in __vm_mem_region_delete() KVM: selftests: aarch64: Add virt_get_pte_hva() library function KVM: selftests: Add a userfaultfd library Signed-off-by: Marc Zyngier <[email protected]>
- Loading branch information
Showing
15 changed files
with
1,723 additions
and
276 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Copyright (C) 2014 Felix Fietkau <[email protected]> | ||
* Copyright (C) 2004 - 2009 Ivo van Doorn <[email protected]> | ||
*/ | ||
|
||
#ifndef _LINUX_BITFIELD_H | ||
#define _LINUX_BITFIELD_H | ||
|
||
#include <linux/build_bug.h> | ||
#include <asm/byteorder.h> | ||
|
||
/* | ||
* Bitfield access macros | ||
* | ||
* FIELD_{GET,PREP} macros take as first parameter shifted mask | ||
* from which they extract the base mask and shift amount. | ||
* Mask must be a compilation time constant. | ||
* | ||
* Example: | ||
* | ||
* #define REG_FIELD_A GENMASK(6, 0) | ||
* #define REG_FIELD_B BIT(7) | ||
* #define REG_FIELD_C GENMASK(15, 8) | ||
* #define REG_FIELD_D GENMASK(31, 16) | ||
* | ||
* Get: | ||
* a = FIELD_GET(REG_FIELD_A, reg); | ||
* b = FIELD_GET(REG_FIELD_B, reg); | ||
* | ||
* Set: | ||
* reg = FIELD_PREP(REG_FIELD_A, 1) | | ||
* FIELD_PREP(REG_FIELD_B, 0) | | ||
* FIELD_PREP(REG_FIELD_C, c) | | ||
* FIELD_PREP(REG_FIELD_D, 0x40); | ||
* | ||
* Modify: | ||
* reg &= ~REG_FIELD_C; | ||
* reg |= FIELD_PREP(REG_FIELD_C, c); | ||
*/ | ||
|
||
#define __bf_shf(x) (__builtin_ffsll(x) - 1) | ||
|
||
#define __scalar_type_to_unsigned_cases(type) \ | ||
unsigned type: (unsigned type)0, \ | ||
signed type: (unsigned type)0 | ||
|
||
#define __unsigned_scalar_typeof(x) typeof( \ | ||
_Generic((x), \ | ||
char: (unsigned char)0, \ | ||
__scalar_type_to_unsigned_cases(char), \ | ||
__scalar_type_to_unsigned_cases(short), \ | ||
__scalar_type_to_unsigned_cases(int), \ | ||
__scalar_type_to_unsigned_cases(long), \ | ||
__scalar_type_to_unsigned_cases(long long), \ | ||
default: (x))) | ||
|
||
#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x)) | ||
|
||
#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ | ||
({ \ | ||
BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ | ||
_pfx "mask is not constant"); \ | ||
BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \ | ||
BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ | ||
~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ | ||
_pfx "value too large for the field"); \ | ||
BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \ | ||
__bf_cast_unsigned(_reg, ~0ull), \ | ||
_pfx "type of reg too small for mask"); \ | ||
__BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ | ||
(1ULL << __bf_shf(_mask))); \ | ||
}) | ||
|
||
/** | ||
* FIELD_MAX() - produce the maximum value representable by a field | ||
* @_mask: shifted mask defining the field's length and position | ||
* | ||
* FIELD_MAX() returns the maximum value that can be held in the field | ||
* specified by @_mask. | ||
*/ | ||
#define FIELD_MAX(_mask) \ | ||
({ \ | ||
__BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_MAX: "); \ | ||
(typeof(_mask))((_mask) >> __bf_shf(_mask)); \ | ||
}) | ||
|
||
/** | ||
* FIELD_FIT() - check if value fits in the field | ||
* @_mask: shifted mask defining the field's length and position | ||
* @_val: value to test against the field | ||
* | ||
* Return: true if @_val can fit inside @_mask, false if @_val is too big. | ||
*/ | ||
#define FIELD_FIT(_mask, _val) \ | ||
({ \ | ||
__BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_FIT: "); \ | ||
!((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ | ||
}) | ||
|
||
/** | ||
* FIELD_PREP() - prepare a bitfield element | ||
* @_mask: shifted mask defining the field's length and position | ||
* @_val: value to put in the field | ||
* | ||
* FIELD_PREP() masks and shifts up the value. The result should | ||
* be combined with other fields of the bitfield using logical OR. | ||
*/ | ||
#define FIELD_PREP(_mask, _val) \ | ||
({ \ | ||
__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ | ||
((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ | ||
}) | ||
|
||
/** | ||
* FIELD_GET() - extract a bitfield element | ||
* @_mask: shifted mask defining the field's length and position | ||
* @_reg: value of entire bitfield | ||
* | ||
* FIELD_GET() extracts the field specified by @_mask from the | ||
* bitfield passed in as @_reg by masking and shifting it down. | ||
*/ | ||
#define FIELD_GET(_mask, _reg) \ | ||
({ \ | ||
__BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ | ||
(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ | ||
}) | ||
|
||
extern void __compiletime_error("value doesn't fit into mask") | ||
__field_overflow(void); | ||
extern void __compiletime_error("bad bitfield mask") | ||
__bad_mask(void); | ||
static __always_inline u64 field_multiplier(u64 field) | ||
{ | ||
if ((field | (field - 1)) & ((field | (field - 1)) + 1)) | ||
__bad_mask(); | ||
return field & -field; | ||
} | ||
static __always_inline u64 field_mask(u64 field) | ||
{ | ||
return field / field_multiplier(field); | ||
} | ||
#define field_max(field) ((typeof(field))field_mask(field)) | ||
#define ____MAKE_OP(type,base,to,from) \ | ||
static __always_inline __##type type##_encode_bits(base v, base field) \ | ||
{ \ | ||
if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ | ||
__field_overflow(); \ | ||
return to((v & field_mask(field)) * field_multiplier(field)); \ | ||
} \ | ||
static __always_inline __##type type##_replace_bits(__##type old, \ | ||
base val, base field) \ | ||
{ \ | ||
return (old & ~to(field)) | type##_encode_bits(val, field); \ | ||
} \ | ||
static __always_inline void type##p_replace_bits(__##type *p, \ | ||
base val, base field) \ | ||
{ \ | ||
*p = (*p & ~to(field)) | type##_encode_bits(val, field); \ | ||
} \ | ||
static __always_inline base type##_get_bits(__##type v, base field) \ | ||
{ \ | ||
return (from(v) & field)/field_multiplier(field); \ | ||
} | ||
#define __MAKE_OP(size) \ | ||
____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \ | ||
____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \ | ||
____MAKE_OP(u##size,u##size,,) | ||
____MAKE_OP(u8,u8,,) | ||
__MAKE_OP(16) | ||
__MAKE_OP(32) | ||
__MAKE_OP(64) | ||
#undef __MAKE_OP | ||
#undef ____MAKE_OP | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.