tools/testing/selftests/kvm/s390/tprot.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/s390/tprot.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/s390/tprot.c- Extension
.c- Size
- 7268 bytes
- Lines
- 245
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
test_util.hkvm_syscalls.hkvm_util.hkselftest.hucall_common.hprocessor.h
Detected Declarations
struct testenum permissionenum stagefunction set_storage_keyfunction test_protectionfunction perform_next_stagefunction guest_codefunction main
Annotated Snippet
struct test {
enum stage stage;
void *addr;
u8 key;
enum permission expected;
} tests[] = {
/*
* We perform each test in the array by executing TEST PROTECTION on
* the specified addr with the specified key and checking if the returned
* permissions match the expected value.
* Both guest and host cooperate to set up the required test conditions.
* A central condition is that the page targeted by addr has to be DAT
* protected in the host mappings, in order for KVM to emulate the
* TEST PROTECTION instruction.
* Since the page tables are shared, the host uses mprotect to achieve
* this.
*
* Test resulting in RW_PROTECTED/TRANSL_UNAVAIL will be interpreted
* by SIE, not KVM, but there is no harm in testing them also.
* See Enhanced Suppression-on-Protection Facilities in the
* Interpretive-Execution Mode
*/
/*
* guest: set storage key of page_store_prot to 1
* storage key of page_fetch_prot to 9 and enable
* protection for it
* STAGE_INIT_SIMPLE
* host: write protect both via mprotect
*/
/* access key 0 matches any storage key -> RW */
{ TEST_SIMPLE, page_store_prot, 0x00, READ_WRITE },
/* access key matches storage key -> RW */
{ TEST_SIMPLE, page_store_prot, 0x10, READ_WRITE },
/* mismatched keys, but no fetch protection -> RO */
{ TEST_SIMPLE, page_store_prot, 0x20, READ },
/* access key 0 matches any storage key -> RW */
{ TEST_SIMPLE, page_fetch_prot, 0x00, READ_WRITE },
/* access key matches storage key -> RW */
{ TEST_SIMPLE, page_fetch_prot, 0x90, READ_WRITE },
/* mismatched keys, fetch protection -> inaccessible */
{ TEST_SIMPLE, page_fetch_prot, 0x10, RW_PROTECTED },
/* page 0 not mapped yet -> translation not available */
{ TEST_SIMPLE, (void *)0x00, 0x10, TRANSL_UNAVAIL },
/*
* host: try to map page 0
* guest: set storage key of page 0 to 9 and enable fetch protection
* STAGE_INIT_FETCH_PROT_OVERRIDE
* host: write protect page 0
* enable fetch protection override
*/
/* mismatched keys, fetch protection, but override applies -> RO */
{ TEST_FETCH_PROT_OVERRIDE, (void *)0x00, 0x10, READ },
/* mismatched keys, fetch protection, override applies to 0-2048 only -> inaccessible */
{ TEST_FETCH_PROT_OVERRIDE, (void *)2049, 0x10, RW_PROTECTED },
/*
* host: enable storage protection override
*/
/* mismatched keys, but override applies (storage key 9) -> RW */
{ TEST_STORAGE_PROT_OVERRIDE, page_fetch_prot, 0x10, READ_WRITE },
/* mismatched keys, no fetch protection, override doesn't apply -> RO */
{ TEST_STORAGE_PROT_OVERRIDE, page_store_prot, 0x20, READ },
/* mismatched keys, but override applies (storage key 9) -> RW */
{ TEST_STORAGE_PROT_OVERRIDE, (void *)2049, 0x10, READ_WRITE },
/* end marker */
{ STAGE_END, 0, 0, 0 },
};
static enum stage perform_next_stage(int *i, bool mapped_0)
{
enum stage stage = tests[*i].stage;
enum permission result;
bool skip;
for (; tests[*i].stage == stage; (*i)++) {
/*
* Some fetch protection override tests require that page 0
* be mapped, however, when the hosts tries to map that page via
* vm_alloc, it may happen that some other page gets mapped
* instead.
* In order to skip these tests we detect this inside the guest
*/
skip = tests[*i].addr < (void *)PAGE_SIZE &&
tests[*i].expected != TRANSL_UNAVAIL &&
!mapped_0;
if (!skip) {
result = test_protection(tests[*i].addr, tests[*i].key);
__GUEST_ASSERT(result == tests[*i].expected,
"Wanted %u, got %u, for i = %u",
tests[*i].expected, result, *i);
}
Annotation
- Immediate include surface: `test_util.h`, `kvm_syscalls.h`, `kvm_util.h`, `kselftest.h`, `ucall_common.h`, `processor.h`.
- Detected declarations: `struct test`, `enum permission`, `enum stage`, `function set_storage_key`, `function test_protection`, `function perform_next_stage`, `function guest_code`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.