···34033403or if no page table is present for the addresses (e.g. when using34043404hugepages).3405340534063406+4.108 KVM_PPC_GET_CPU_CHAR34073407+34083408+Capability: KVM_CAP_PPC_GET_CPU_CHAR34093409+Architectures: powerpc34103410+Type: vm ioctl34113411+Parameters: struct kvm_ppc_cpu_char (out)34123412+Returns: 0 on successful completion34133413+ -EFAULT if struct kvm_ppc_cpu_char cannot be written34143414+34153415+This ioctl gives userspace information about certain characteristics34163416+of the CPU relating to speculative execution of instructions and34173417+possible information leakage resulting from speculative execution (see34183418+CVE-2017-5715, CVE-2017-5753 and CVE-2017-5754). The information is34193419+returned in struct kvm_ppc_cpu_char, which looks like this:34203420+34213421+struct kvm_ppc_cpu_char {34223422+ __u64 character; /* characteristics of the CPU */34233423+ __u64 behaviour; /* recommended software behaviour */34243424+ __u64 character_mask; /* valid bits in character */34253425+ __u64 behaviour_mask; /* valid bits in behaviour */34263426+};34273427+34283428+For extensibility, the character_mask and behaviour_mask fields34293429+indicate which bits of character and behaviour have been filled in by34303430+the kernel. If the set of defined bits is extended in future then34313431+userspace will be able to tell whether it is running on a kernel that34323432+knows about the new bits.34333433+34343434+The character field describes attributes of the CPU which can help34353435+with preventing inadvertent information disclosure - specifically,34363436+whether there is an instruction to flash-invalidate the L1 data cache34373437+(ori 30,30,0 or mtspr SPRN_TRIG2,rN), whether the L1 data cache is set34383438+to a mode where entries can only be used by the thread that created34393439+them, whether the bcctr[l] instruction prevents speculation, and34403440+whether a speculation barrier instruction (ori 31,31,0) is provided.34413441+34423442+The behaviour field describes actions that software should take to34433443+prevent inadvertent information disclosure, and thus describes which34443444+vulnerabilities the hardware is subject to; specifically whether the34453445+L1 data cache should be flushed when returning to user mode from the34463446+kernel, and whether a speculation barrier should be placed between an34473447+array bounds check and the array access.34483448+34493449+These fields use the same bit definitions as the new34503450+H_GET_CPU_CHARACTERISTICS hypercall.34513451+340634525. The kvm_run structure34073453------------------------34083454
+25
arch/powerpc/include/uapi/asm/kvm.h
···443443 __u32 ap_encodings[8];444444};445445446446+/* For KVM_PPC_GET_CPU_CHAR */447447+struct kvm_ppc_cpu_char {448448+ __u64 character; /* characteristics of the CPU */449449+ __u64 behaviour; /* recommended software behaviour */450450+ __u64 character_mask; /* valid bits in character */451451+ __u64 behaviour_mask; /* valid bits in behaviour */452452+};453453+454454+/*455455+ * Values for character and character_mask.456456+ * These are identical to the values used by H_GET_CPU_CHARACTERISTICS.457457+ */458458+#define KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 (1ULL << 63)459459+#define KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED (1ULL << 62)460460+#define KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 (1ULL << 61)461461+#define KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 (1ULL << 60)462462+#define KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV (1ULL << 59)463463+#define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED (1ULL << 58)464464+#define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF (1ULL << 57)465465+#define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS (1ULL << 56)466466+467467+#define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY (1ULL << 63)468468+#define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR (1ULL << 62)469469+#define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ULL << 61)470470+446471/* Per-vcpu XICS interrupt controller state */447472#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)448473
+131
arch/powerpc/kvm/powerpc.c
···3939#include <asm/iommu.h>4040#include <asm/switch_to.h>4141#include <asm/xive.h>4242+#ifdef CONFIG_PPC_PSERIES4343+#include <asm/hvcall.h>4444+#include <asm/plpar_wrappers.h>4545+#endif42464347#include "timing.h"4448#include "irq.h"···552548#ifdef CONFIG_KVM_XICS553549 case KVM_CAP_IRQ_XICS:554550#endif551551+ case KVM_CAP_PPC_GET_CPU_CHAR:555552 r = 1;556553 break;557554···17641759 return r;17651760}1766176117621762+#ifdef CONFIG_PPC_BOOK3S_6417631763+/*17641764+ * These functions check whether the underlying hardware is safe17651765+ * against attacks based on observing the effects of speculatively17661766+ * executed instructions, and whether it supplies instructions for17671767+ * use in workarounds. The information comes from firmware, either17681768+ * via the device tree on powernv platforms or from an hcall on17691769+ * pseries platforms.17701770+ */17711771+#ifdef CONFIG_PPC_PSERIES17721772+static int pseries_get_cpu_char(struct kvm_ppc_cpu_char *cp)17731773+{17741774+ struct h_cpu_char_result c;17751775+ unsigned long rc;17761776+17771777+ if (!machine_is(pseries))17781778+ return -ENOTTY;17791779+17801780+ rc = plpar_get_cpu_characteristics(&c);17811781+ if (rc == H_SUCCESS) {17821782+ cp->character = c.character;17831783+ cp->behaviour = c.behaviour;17841784+ cp->character_mask = KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 |17851785+ KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED |17861786+ KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 |17871787+ KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 |17881788+ KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV |17891789+ KVM_PPC_CPU_CHAR_BR_HINT_HONOURED |17901790+ KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF |17911791+ KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;17921792+ cp->behaviour_mask = KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY |17931793+ KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR |17941794+ KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;17951795+ }17961796+ return 0;17971797+}17981798+#else17991799+static int pseries_get_cpu_char(struct kvm_ppc_cpu_char *cp)18001800+{18011801+ return -ENOTTY;18021802+}18031803+#endif18041804+18051805+static inline bool have_fw_feat(struct device_node *fw_features,18061806+ const char *state, const char *name)18071807+{18081808+ struct device_node *np;18091809+ bool r = false;18101810+18111811+ np = of_get_child_by_name(fw_features, name);18121812+ if (np) {18131813+ r = of_property_read_bool(np, state);18141814+ of_node_put(np);18151815+ }18161816+ return r;18171817+}18181818+18191819+static int kvmppc_get_cpu_char(struct kvm_ppc_cpu_char *cp)18201820+{18211821+ struct device_node *np, *fw_features;18221822+ int r;18231823+18241824+ memset(cp, 0, sizeof(*cp));18251825+ r = pseries_get_cpu_char(cp);18261826+ if (r != -ENOTTY)18271827+ return r;18281828+18291829+ np = of_find_node_by_name(NULL, "ibm,opal");18301830+ if (np) {18311831+ fw_features = of_get_child_by_name(np, "fw-features");18321832+ of_node_put(np);18331833+ if (!fw_features)18341834+ return 0;18351835+ if (have_fw_feat(fw_features, "enabled",18361836+ "inst-spec-barrier-ori31,31,0"))18371837+ cp->character |= KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31;18381838+ if (have_fw_feat(fw_features, "enabled",18391839+ "fw-bcctrl-serialized"))18401840+ cp->character |= KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED;18411841+ if (have_fw_feat(fw_features, "enabled",18421842+ "inst-l1d-flush-ori30,30,0"))18431843+ cp->character |= KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30;18441844+ if (have_fw_feat(fw_features, "enabled",18451845+ "inst-l1d-flush-trig2"))18461846+ cp->character |= KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2;18471847+ if (have_fw_feat(fw_features, "enabled",18481848+ "fw-l1d-thread-split"))18491849+ cp->character |= KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV;18501850+ if (have_fw_feat(fw_features, "enabled",18511851+ "fw-count-cache-disabled"))18521852+ cp->character |= KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;18531853+ cp->character_mask = KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 |18541854+ KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED |18551855+ KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 |18561856+ KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 |18571857+ KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV |18581858+ KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;18591859+18601860+ if (have_fw_feat(fw_features, "enabled",18611861+ "speculation-policy-favor-security"))18621862+ cp->behaviour |= KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY;18631863+ if (!have_fw_feat(fw_features, "disabled",18641864+ "needs-l1d-flush-msr-pr-0-to-1"))18651865+ cp->behaviour |= KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR;18661866+ if (!have_fw_feat(fw_features, "disabled",18671867+ "needs-spec-barrier-for-bound-checks"))18681868+ cp->behaviour |= KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;18691869+ cp->behaviour_mask = KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY |18701870+ KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR |18711871+ KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;18721872+18731873+ of_node_put(fw_features);18741874+ }18751875+18761876+ return 0;18771877+}18781878+#endif18791879+17671880long kvm_arch_vm_ioctl(struct file *filp,17681881 unsigned int ioctl, unsigned long arg)17691882{···19811858 goto out;19821859 r = kvm->arch.kvm_ops->get_rmmu_info(kvm, &info);19831860 if (r >= 0 && copy_to_user(argp, &info, sizeof(info)))18611861+ r = -EFAULT;18621862+ break;18631863+ }18641864+ case KVM_PPC_GET_CPU_CHAR: {18651865+ struct kvm_ppc_cpu_char cpuchar;18661866+18671867+ r = kvmppc_get_cpu_char(&cpuchar);18681868+ if (r >= 0 && copy_to_user(argp, &cpuchar, sizeof(cpuchar)))19841869 r = -EFAULT;19851870 break;19861871 }
+3
include/uapi/linux/kvm.h
···932932#define KVM_CAP_HYPERV_SYNIC2 148933933#define KVM_CAP_HYPERV_VP_INDEX 149934934#define KVM_CAP_S390_AIS_MIGRATION 150935935+#define KVM_CAP_PPC_GET_CPU_CHAR 151935936936937#ifdef KVM_CAP_IRQ_ROUTING937938···12621261#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)12631262/* Available with KVM_CAP_PPC_RADIX_MMU */12641263#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)12641264+/* Available with KVM_CAP_PPC_GET_CPU_CHAR */12651265+#define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)1265126612661267/* ioctl for vm fd */12671268#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)