• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision95ea96e8b1610f2d1bfa2abd0d12c40d647e563d (tree)
Time2022-01-20 20:47:52
AuthorMarc Zyngier <maz@kern...>
CommiterPeter Maydell

Log Message

hw/arm/virt: KVM: Enable PAuth when supported by the host

Add basic support for Pointer Authentication when running a KVM
guest and that the host supports it, loosely based on the SVE
support.

Although the feature is enabled by default when the host advertises
it, it is possible to disable it by setting the 'pauth=off' CPU
property. The 'pauth' comment is removed from cpu-features.rst,
as it is now common to both TCG and KVM.

Tested on an Apple M1 running 5.16-rc6.

Cc: Eric Auger <eric.auger@redhat.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220107150154.2490308-1-maz@kernel.org
[PMM: fixed indentation]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Change Summary

Incremental Difference

--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -217,10 +217,6 @@ TCG VCPU Features
217217 TCG VCPU features are CPU features that are specific to TCG.
218218 Below is the list of TCG VCPU features and their descriptions.
219219
220- pauth Enable or disable ``FEAT_Pauth``, pointer
221- authentication. By default, the feature is
222- enabled with ``-cpu max``.
223-
224220 pauth-impdef When ``FEAT_Pauth`` is enabled, either the
225221 *impdef* (Implementation Defined) algorithm
226222 is enabled or the *architected* QARMA algorithm
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1380,17 +1380,10 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
13801380 return;
13811381 }
13821382
1383- /*
1384- * KVM does not support modifications to this feature.
1385- * We have not registered the cpu properties when KVM
1386- * is in use, so the user will not be able to set them.
1387- */
1388- if (!kvm_enabled()) {
1389- arm_cpu_pauth_finalize(cpu, &local_err);
1390- if (local_err != NULL) {
1391- error_propagate(errp, local_err);
1392- return;
1393- }
1383+ arm_cpu_pauth_finalize(cpu, &local_err);
1384+ if (local_err != NULL) {
1385+ error_propagate(errp, local_err);
1386+ return;
13941387 }
13951388 }
13961389
@@ -2091,6 +2084,7 @@ static void arm_host_initfn(Object *obj)
20912084 kvm_arm_set_cpu_features_from_host(cpu);
20922085 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
20932086 aarch64_add_sve_properties(obj);
2087+ aarch64_add_pauth_properties(obj);
20942088 }
20952089 #else
20962090 hvf_arm_set_cpu_features_from_host(cpu);
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1076,6 +1076,7 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
10761076 void aarch64_sve_change_el(CPUARMState *env, int old_el,
10771077 int new_el, bool el0_a64);
10781078 void aarch64_add_sve_properties(Object *obj);
1079+void aarch64_add_pauth_properties(Object *obj);
10791080
10801081 /*
10811082 * SVE registers are encoded in KVM's memory in an endianness-invariant format.
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -630,6 +630,15 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
630630 int arch_val = 0, impdef_val = 0;
631631 uint64_t t;
632632
633+ /* Exit early if PAuth is enabled, and fall through to disable it */
634+ if (kvm_enabled() && cpu->prop_pauth) {
635+ if (!cpu_isar_feature(aa64_pauth, cpu)) {
636+ error_setg(errp, "'pauth' feature not supported by KVM on this host");
637+ }
638+
639+ return;
640+ }
641+
633642 /* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
634643 if (cpu->prop_pauth) {
635644 if (cpu->prop_pauth_impdef) {
@@ -655,6 +664,23 @@ static Property arm_cpu_pauth_property =
655664 static Property arm_cpu_pauth_impdef_property =
656665 DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
657666
667+void aarch64_add_pauth_properties(Object *obj)
668+{
669+ ARMCPU *cpu = ARM_CPU(obj);
670+
671+ /* Default to PAUTH on, with the architected algorithm on TCG. */
672+ qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
673+ if (kvm_enabled()) {
674+ /*
675+ * Mirror PAuth support from the probed sysregs back into the
676+ * property for KVM. Is it just a bit backward? Yes it is!
677+ */
678+ cpu->prop_pauth = cpu_isar_feature(aa64_pauth, cpu);
679+ } else {
680+ qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
681+ }
682+}
683+
658684 /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
659685 * otherwise, a CPU with as many features enabled as our emulation supports.
660686 * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -829,13 +855,10 @@ static void aarch64_max_initfn(Object *obj)
829855 cpu->dcz_blocksize = 7; /* 512 bytes */
830856 #endif
831857
832- /* Default to PAUTH on, with the architected algorithm. */
833- qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
834- qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
835-
836858 bitmap_fill(cpu->sve_vq_supported, ARM_MAX_VQ);
837859 }
838860
861+ aarch64_add_pauth_properties(obj);
839862 aarch64_add_sve_properties(obj);
840863 object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
841864 cpu_max_set_sve_max_vq, NULL, NULL);
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -491,6 +491,12 @@ static int read_sys_reg64(int fd, uint64_t *pret, uint64_t id)
491491 return ioctl(fd, KVM_GET_ONE_REG, &idreg);
492492 }
493493
494+static bool kvm_arm_pauth_supported(void)
495+{
496+ return (kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_ADDRESS) &&
497+ kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC));
498+}
499+
494500 bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
495501 {
496502 /* Identify the feature bits corresponding to the host CPU, and
@@ -521,6 +527,17 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
521527 */
522528 struct kvm_vcpu_init init = { .target = -1, };
523529
530+ /*
531+ * Ask for Pointer Authentication if supported. We can't play the
532+ * SVE trick of synthesising the ID reg as KVM won't tell us
533+ * whether we have the architected or IMPDEF version of PAuth, so
534+ * we have to use the actual ID regs.
535+ */
536+ if (kvm_arm_pauth_supported()) {
537+ init.features[0] |= (1 << KVM_ARM_VCPU_PTRAUTH_ADDRESS |
538+ 1 << KVM_ARM_VCPU_PTRAUTH_GENERIC);
539+ }
540+
524541 if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
525542 return false;
526543 }
@@ -865,6 +882,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
865882 assert(kvm_arm_sve_supported());
866883 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
867884 }
885+ if (cpu_isar_feature(aa64_pauth, cpu)) {
886+ cpu->kvm_init_features[0] |= (1 << KVM_ARM_VCPU_PTRAUTH_ADDRESS |
887+ 1 << KVM_ARM_VCPU_PTRAUTH_GENERIC);
888+ }
868889
869890 /* Do KVM_ARM_VCPU_INIT ioctl */
870891 ret = kvm_arm_vcpu_init(cs);