Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/kvm/arm64/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  aarch32_id_regs.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * aarch32_id_regs - Test for ID register behavior on AArch64-only systems
 *
 * Copyright (c) 2022 Google LLC.
 *
 * Test that KVM handles the AArch64 views of the AArch32 ID registers as RAZ
 * and WI from userspace.
 */


#include <stdint.h>

#include "kvm_util.h"
#include "processor.h"
#include "test_util.h"
#include <linux/bitfield.h>

#define BAD_ID_REG_VAL 0x1badc0deul

#define GUEST_ASSERT_REG_RAZ(reg) GUEST_ASSERT_EQ(read_sysreg_s(reg), 0)

static void guest_main(void)
{
 GUEST_ASSERT_REG_RAZ(SYS_ID_PFR0_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_PFR1_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_DFR0_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_AFR0_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR0_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR1_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR2_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR3_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR0_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR1_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR2_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR3_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR4_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR5_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR4_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_ISAR6_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_MVFR0_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_MVFR1_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_MVFR2_EL1);
 GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 3));
 GUEST_ASSERT_REG_RAZ(SYS_ID_PFR2_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_DFR1_EL1);
 GUEST_ASSERT_REG_RAZ(SYS_ID_MMFR5_EL1);
 GUEST_ASSERT_REG_RAZ(sys_reg(3, 0, 0, 3, 7));

 GUEST_DONE();
}

static void test_guest_raz(struct kvm_vcpu *vcpu)
{
 struct ucall uc;

 vcpu_run(vcpu);

 switch (get_ucall(vcpu, &uc)) {
 case UCALL_ABORT:
  REPORT_GUEST_ASSERT(uc);
  break;
 case UCALL_DONE:
  break;
 default:
  TEST_FAIL("Unexpected ucall: %lu", uc.cmd);
 }
}

static uint64_t raz_wi_reg_ids[] = {
 KVM_ARM64_SYS_REG(SYS_ID_PFR0_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_PFR1_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_DFR0_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_MMFR0_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_MMFR1_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_MMFR2_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_MMFR3_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR0_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR1_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR2_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR3_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR4_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR5_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_MMFR4_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_ISAR6_EL1),
 KVM_ARM64_SYS_REG(SYS_MVFR0_EL1),
 KVM_ARM64_SYS_REG(SYS_MVFR1_EL1),
 KVM_ARM64_SYS_REG(SYS_MVFR2_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_PFR2_EL1),
 KVM_ARM64_SYS_REG(SYS_ID_MMFR5_EL1),
};

static void test_user_raz_wi(struct kvm_vcpu *vcpu)
{
 int i;

 for (i = 0; i < ARRAY_SIZE(raz_wi_reg_ids); i++) {
  uint64_t reg_id = raz_wi_reg_ids[i];
  uint64_t val;

  val = vcpu_get_reg(vcpu, reg_id);
  TEST_ASSERT_EQ(val, 0);

  /*
 * Expect the ioctl to succeed with no effect on the register
 * value.
 */

  vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);

  val = vcpu_get_reg(vcpu, reg_id);
  TEST_ASSERT_EQ(val, 0);
 }
}

static uint64_t raz_invariant_reg_ids[] = {
 KVM_ARM64_SYS_REG(SYS_ID_AFR0_EL1),
 KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 3)),
 KVM_ARM64_SYS_REG(SYS_ID_DFR1_EL1),
 KVM_ARM64_SYS_REG(sys_reg(3, 0, 0, 3, 7)),
};

static void test_user_raz_invariant(struct kvm_vcpu *vcpu)
{
 int i, r;

 for (i = 0; i < ARRAY_SIZE(raz_invariant_reg_ids); i++) {
  uint64_t reg_id = raz_invariant_reg_ids[i];
  uint64_t val;

  val = vcpu_get_reg(vcpu, reg_id);
  TEST_ASSERT_EQ(val, 0);

  r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
  TEST_ASSERT(r < 0 && errno == EINVAL,
       "unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);

  val = vcpu_get_reg(vcpu, reg_id);
  TEST_ASSERT_EQ(val, 0);
 }
}



static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)
{
 uint64_t val, el0;

 val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));

 el0 = FIELD_GET(ID_AA64PFR0_EL1_EL0, val);
 return el0 == ID_AA64PFR0_EL1_EL0_IMP;
}

int main(void)
{
 struct kvm_vcpu *vcpu;
 struct kvm_vm *vm;

 vm = vm_create_with_one_vcpu(&vcpu, guest_main);

 TEST_REQUIRE(vcpu_aarch64_only(vcpu));

 test_user_raz_wi(vcpu);
 test_user_raz_invariant(vcpu);
 test_guest_raz(vcpu);

 kvm_vm_free(vm);
}

Messung V0.5
C=95 H=93 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© 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 und die Messung sind noch experimentell.