Skip to content

Commit adde047

Browse files
author
Marc Zyngier
committed
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]>
2 parents 02f6fdd + ff2b550 commit adde047

File tree

15 files changed

+1723
-276
lines changed

15 files changed

+1723
-276
lines changed

tools/include/linux/bitfield.h

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2014 Felix Fietkau <[email protected]>
4+
* Copyright (C) 2004 - 2009 Ivo van Doorn <[email protected]>
5+
*/
6+
7+
#ifndef _LINUX_BITFIELD_H
8+
#define _LINUX_BITFIELD_H
9+
10+
#include <linux/build_bug.h>
11+
#include <asm/byteorder.h>
12+
13+
/*
14+
* Bitfield access macros
15+
*
16+
* FIELD_{GET,PREP} macros take as first parameter shifted mask
17+
* from which they extract the base mask and shift amount.
18+
* Mask must be a compilation time constant.
19+
*
20+
* Example:
21+
*
22+
* #define REG_FIELD_A GENMASK(6, 0)
23+
* #define REG_FIELD_B BIT(7)
24+
* #define REG_FIELD_C GENMASK(15, 8)
25+
* #define REG_FIELD_D GENMASK(31, 16)
26+
*
27+
* Get:
28+
* a = FIELD_GET(REG_FIELD_A, reg);
29+
* b = FIELD_GET(REG_FIELD_B, reg);
30+
*
31+
* Set:
32+
* reg = FIELD_PREP(REG_FIELD_A, 1) |
33+
* FIELD_PREP(REG_FIELD_B, 0) |
34+
* FIELD_PREP(REG_FIELD_C, c) |
35+
* FIELD_PREP(REG_FIELD_D, 0x40);
36+
*
37+
* Modify:
38+
* reg &= ~REG_FIELD_C;
39+
* reg |= FIELD_PREP(REG_FIELD_C, c);
40+
*/
41+
42+
#define __bf_shf(x) (__builtin_ffsll(x) - 1)
43+
44+
#define __scalar_type_to_unsigned_cases(type) \
45+
unsigned type: (unsigned type)0, \
46+
signed type: (unsigned type)0
47+
48+
#define __unsigned_scalar_typeof(x) typeof( \
49+
_Generic((x), \
50+
char: (unsigned char)0, \
51+
__scalar_type_to_unsigned_cases(char), \
52+
__scalar_type_to_unsigned_cases(short), \
53+
__scalar_type_to_unsigned_cases(int), \
54+
__scalar_type_to_unsigned_cases(long), \
55+
__scalar_type_to_unsigned_cases(long long), \
56+
default: (x)))
57+
58+
#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x))
59+
60+
#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
61+
({ \
62+
BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
63+
_pfx "mask is not constant"); \
64+
BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \
65+
BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
66+
~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
67+
_pfx "value too large for the field"); \
68+
BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
69+
__bf_cast_unsigned(_reg, ~0ull), \
70+
_pfx "type of reg too small for mask"); \
71+
__BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
72+
(1ULL << __bf_shf(_mask))); \
73+
})
74+
75+
/**
76+
* FIELD_MAX() - produce the maximum value representable by a field
77+
* @_mask: shifted mask defining the field's length and position
78+
*
79+
* FIELD_MAX() returns the maximum value that can be held in the field
80+
* specified by @_mask.
81+
*/
82+
#define FIELD_MAX(_mask) \
83+
({ \
84+
__BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_MAX: "); \
85+
(typeof(_mask))((_mask) >> __bf_shf(_mask)); \
86+
})
87+
88+
/**
89+
* FIELD_FIT() - check if value fits in the field
90+
* @_mask: shifted mask defining the field's length and position
91+
* @_val: value to test against the field
92+
*
93+
* Return: true if @_val can fit inside @_mask, false if @_val is too big.
94+
*/
95+
#define FIELD_FIT(_mask, _val) \
96+
({ \
97+
__BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_FIT: "); \
98+
!((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \
99+
})
100+
101+
/**
102+
* FIELD_PREP() - prepare a bitfield element
103+
* @_mask: shifted mask defining the field's length and position
104+
* @_val: value to put in the field
105+
*
106+
* FIELD_PREP() masks and shifts up the value. The result should
107+
* be combined with other fields of the bitfield using logical OR.
108+
*/
109+
#define FIELD_PREP(_mask, _val) \
110+
({ \
111+
__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
112+
((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
113+
})
114+
115+
/**
116+
* FIELD_GET() - extract a bitfield element
117+
* @_mask: shifted mask defining the field's length and position
118+
* @_reg: value of entire bitfield
119+
*
120+
* FIELD_GET() extracts the field specified by @_mask from the
121+
* bitfield passed in as @_reg by masking and shifting it down.
122+
*/
123+
#define FIELD_GET(_mask, _reg) \
124+
({ \
125+
__BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
126+
(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
127+
})
128+
129+
extern void __compiletime_error("value doesn't fit into mask")
130+
__field_overflow(void);
131+
extern void __compiletime_error("bad bitfield mask")
132+
__bad_mask(void);
133+
static __always_inline u64 field_multiplier(u64 field)
134+
{
135+
if ((field | (field - 1)) & ((field | (field - 1)) + 1))
136+
__bad_mask();
137+
return field & -field;
138+
}
139+
static __always_inline u64 field_mask(u64 field)
140+
{
141+
return field / field_multiplier(field);
142+
}
143+
#define field_max(field) ((typeof(field))field_mask(field))
144+
#define ____MAKE_OP(type,base,to,from) \
145+
static __always_inline __##type type##_encode_bits(base v, base field) \
146+
{ \
147+
if (__builtin_constant_p(v) && (v & ~field_mask(field))) \
148+
__field_overflow(); \
149+
return to((v & field_mask(field)) * field_multiplier(field)); \
150+
} \
151+
static __always_inline __##type type##_replace_bits(__##type old, \
152+
base val, base field) \
153+
{ \
154+
return (old & ~to(field)) | type##_encode_bits(val, field); \
155+
} \
156+
static __always_inline void type##p_replace_bits(__##type *p, \
157+
base val, base field) \
158+
{ \
159+
*p = (*p & ~to(field)) | type##_encode_bits(val, field); \
160+
} \
161+
static __always_inline base type##_get_bits(__##type v, base field) \
162+
{ \
163+
return (from(v) & field)/field_multiplier(field); \
164+
}
165+
#define __MAKE_OP(size) \
166+
____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
167+
____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
168+
____MAKE_OP(u##size,u##size,,)
169+
____MAKE_OP(u8,u8,,)
170+
__MAKE_OP(16)
171+
__MAKE_OP(32)
172+
__MAKE_OP(64)
173+
#undef __MAKE_OP
174+
#undef ____MAKE_OP
175+
176+
#endif

tools/testing/selftests/kvm/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
/aarch64/debug-exceptions
55
/aarch64/get-reg-list
66
/aarch64/hypercalls
7+
/aarch64/page_fault_test
78
/aarch64/psci_test
89
/aarch64/vcpu_width_config
910
/aarch64/vgic_init

tools/testing/selftests/kvm/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ LIBKVM += lib/perf_test_util.c
4747
LIBKVM += lib/rbtree.c
4848
LIBKVM += lib/sparsebit.c
4949
LIBKVM += lib/test_util.c
50+
LIBKVM += lib/userfaultfd_util.c
5051

5152
LIBKVM_STRING += lib/string_override.c
5253

@@ -152,6 +153,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
152153
TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
153154
TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
154155
TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
156+
TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
155157
TEST_GEN_PROGS_aarch64 += aarch64/psci_test
156158
TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
157159
TEST_GEN_PROGS_aarch64 += aarch64/vgic_init

0 commit comments

Comments
 (0)