aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@ozlabs.org>2018-01-15 00:06:47 -0500
committerPaul Mackerras <paulus@ozlabs.org>2018-01-18 23:17:01 -0500
commit3214d01f139b7544e870fc0b7fcce8da13c1cb51 (patch)
tree15736d0929131d265751405b3cb262444246ab8c
parent37b95951c58fdf08dc10afa9d02066ed9f176fb5 (diff)
KVM: PPC: Book3S: Provide information about hardware/firmware CVE workarounds
This adds a new ioctl, KVM_PPC_GET_CPU_CHAR, that gives userspace information about the underlying machine's level of vulnerability to the recently announced vulnerabilities CVE-2017-5715, CVE-2017-5753 and CVE-2017-5754, and whether the machine provides instructions to assist software to work around the vulnerabilities. The ioctl returns two u64 words describing characteristics of the CPU and required software behaviour respectively, plus two mask words which indicate which bits have been filled in by the kernel, for extensibility. The bit definitions are the same as for the new H_GET_CPU_CHARACTERISTICS hypercall. There is also a new capability, KVM_CAP_PPC_GET_CPU_CHAR, which indicates whether the new ioctl is available. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r--Documentation/virtual/kvm/api.txt46
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h25
-rw-r--r--arch/powerpc/kvm/powerpc.c131
-rw-r--r--include/uapi/linux/kvm.h3
4 files changed, 205 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 57d3ee9e4bde..fc3ae951bc07 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3403,6 +3403,52 @@ invalid, if invalid pages are written to (e.g. after the end of memory)
3403or if no page table is present for the addresses (e.g. when using 3403or if no page table is present for the addresses (e.g. when using
3404hugepages). 3404hugepages).
3405 3405
34064.108 KVM_PPC_GET_CPU_CHAR
3407
3408Capability: KVM_CAP_PPC_GET_CPU_CHAR
3409Architectures: powerpc
3410Type: vm ioctl
3411Parameters: struct kvm_ppc_cpu_char (out)
3412Returns: 0 on successful completion
3413 -EFAULT if struct kvm_ppc_cpu_char cannot be written
3414
3415This ioctl gives userspace information about certain characteristics
3416of the CPU relating to speculative execution of instructions and
3417possible information leakage resulting from speculative execution (see
3418CVE-2017-5715, CVE-2017-5753 and CVE-2017-5754). The information is
3419returned in struct kvm_ppc_cpu_char, which looks like this:
3420
3421struct kvm_ppc_cpu_char {
3422 __u64 character; /* characteristics of the CPU */
3423 __u64 behaviour; /* recommended software behaviour */
3424 __u64 character_mask; /* valid bits in character */
3425 __u64 behaviour_mask; /* valid bits in behaviour */
3426};
3427
3428For extensibility, the character_mask and behaviour_mask fields
3429indicate which bits of character and behaviour have been filled in by
3430the kernel. If the set of defined bits is extended in future then
3431userspace will be able to tell whether it is running on a kernel that
3432knows about the new bits.
3433
3434The character field describes attributes of the CPU which can help
3435with preventing inadvertent information disclosure - specifically,
3436whether there is an instruction to flash-invalidate the L1 data cache
3437(ori 30,30,0 or mtspr SPRN_TRIG2,rN), whether the L1 data cache is set
3438to a mode where entries can only be used by the thread that created
3439them, whether the bcctr[l] instruction prevents speculation, and
3440whether a speculation barrier instruction (ori 31,31,0) is provided.
3441
3442The behaviour field describes actions that software should take to
3443prevent inadvertent information disclosure, and thus describes which
3444vulnerabilities the hardware is subject to; specifically whether the
3445L1 data cache should be flushed when returning to user mode from the
3446kernel, and whether a speculation barrier should be placed between an
3447array bounds check and the array access.
3448
3449These fields use the same bit definitions as the new
3450H_GET_CPU_CHARACTERISTICS hypercall.
3451
34065. The kvm_run structure 34525. The kvm_run structure
3407------------------------ 3453------------------------
3408 3454
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 61d6049f4c1e..637b7263cb86 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,6 +443,31 @@ struct kvm_ppc_rmmu_info {
443 __u32 ap_encodings[8]; 443 __u32 ap_encodings[8];
444}; 444};
445 445
446/* For KVM_PPC_GET_CPU_CHAR */
447struct kvm_ppc_cpu_char {
448 __u64 character; /* characteristics of the CPU */
449 __u64 behaviour; /* recommended software behaviour */
450 __u64 character_mask; /* valid bits in character */
451 __u64 behaviour_mask; /* valid bits in behaviour */
452};
453
454/*
455 * Values for character and character_mask.
456 * These are identical to the values used by H_GET_CPU_CHARACTERISTICS.
457 */
458#define KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 (1ULL << 63)
459#define KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED (1ULL << 62)
460#define KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 (1ULL << 61)
461#define KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 (1ULL << 60)
462#define KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV (1ULL << 59)
463#define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED (1ULL << 58)
464#define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF (1ULL << 57)
465#define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS (1ULL << 56)
466
467#define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY (1ULL << 63)
468#define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR (1ULL << 62)
469#define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ULL << 61)
470
446/* Per-vcpu XICS interrupt controller state */ 471/* Per-vcpu XICS interrupt controller state */
447#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c) 472#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
448 473
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 1915e86cef6f..0a7c88786ec0 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -39,6 +39,10 @@
39#include <asm/iommu.h> 39#include <asm/iommu.h>
40#include <asm/switch_to.h> 40#include <asm/switch_to.h>
41#include <asm/xive.h> 41#include <asm/xive.h>
42#ifdef CONFIG_PPC_PSERIES
43#include <asm/hvcall.h>
44#include <asm/plpar_wrappers.h>
45#endif
42 46
43#include "timing.h" 47#include "timing.h"
44#include "irq.h" 48#include "irq.h"
@@ -548,6 +552,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
548#ifdef CONFIG_KVM_XICS 552#ifdef CONFIG_KVM_XICS
549 case KVM_CAP_IRQ_XICS: 553 case KVM_CAP_IRQ_XICS:
550#endif 554#endif
555 case KVM_CAP_PPC_GET_CPU_CHAR:
551 r = 1; 556 r = 1;
552 break; 557 break;
553 558
@@ -1759,6 +1764,124 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
1759 return r; 1764 return r;
1760} 1765}
1761 1766
1767#ifdef CONFIG_PPC_BOOK3S_64
1768/*
1769 * These functions check whether the underlying hardware is safe
1770 * against attacks based on observing the effects of speculatively
1771 * executed instructions, and whether it supplies instructions for
1772 * use in workarounds. The information comes from firmware, either
1773 * via the device tree on powernv platforms or from an hcall on
1774 * pseries platforms.
1775 */
1776#ifdef CONFIG_PPC_PSERIES
1777static int pseries_get_cpu_char(struct kvm_ppc_cpu_char *cp)
1778{
1779 struct h_cpu_char_result c;
1780 unsigned long rc;
1781
1782 if (!machine_is(pseries))
1783 return -ENOTTY;
1784
1785 rc = plpar_get_cpu_characteristics(&c);
1786 if (rc == H_SUCCESS) {
1787 cp->character = c.character;
1788 cp->behaviour = c.behaviour;
1789 cp->character_mask = KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 |
1790 KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED |
1791 KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 |
1792 KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 |
1793 KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV |
1794 KVM_PPC_CPU_CHAR_BR_HINT_HONOURED |
1795 KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF |
1796 KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;
1797 cp->behaviour_mask = KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY |
1798 KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR |
1799 KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1800 }
1801 return 0;
1802}
1803#else
1804static int pseries_get_cpu_char(struct kvm_ppc_cpu_char *cp)
1805{
1806 return -ENOTTY;
1807}
1808#endif
1809
1810static inline bool have_fw_feat(struct device_node *fw_features,
1811 const char *state, const char *name)
1812{
1813 struct device_node *np;
1814 bool r = false;
1815
1816 np = of_get_child_by_name(fw_features, name);
1817 if (np) {
1818 r = of_property_read_bool(np, state);
1819 of_node_put(np);
1820 }
1821 return r;
1822}
1823
1824static int kvmppc_get_cpu_char(struct kvm_ppc_cpu_char *cp)
1825{
1826 struct device_node *np, *fw_features;
1827 int r;
1828
1829 memset(cp, 0, sizeof(*cp));
1830 r = pseries_get_cpu_char(cp);
1831 if (r != -ENOTTY)
1832 return r;
1833
1834 np = of_find_node_by_name(NULL, "ibm,opal");
1835 if (np) {
1836 fw_features = of_get_child_by_name(np, "fw-features");
1837 of_node_put(np);
1838 if (!fw_features)
1839 return 0;
1840 if (have_fw_feat(fw_features, "enabled",
1841 "inst-spec-barrier-ori31,31,0"))
1842 cp->character |= KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31;
1843 if (have_fw_feat(fw_features, "enabled",
1844 "fw-bcctrl-serialized"))
1845 cp->character |= KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED;
1846 if (have_fw_feat(fw_features, "enabled",
1847 "inst-l1d-flush-ori30,30,0"))
1848 cp->character |= KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30;
1849 if (have_fw_feat(fw_features, "enabled",
1850 "inst-l1d-flush-trig2"))
1851 cp->character |= KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2;
1852 if (have_fw_feat(fw_features, "enabled",
1853 "fw-l1d-thread-split"))
1854 cp->character |= KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV;
1855 if (have_fw_feat(fw_features, "enabled",
1856 "fw-count-cache-disabled"))
1857 cp->character |= KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;
1858 cp->character_mask = KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 |
1859 KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED |
1860 KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 |
1861 KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 |
1862 KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV |
1863 KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;
1864
1865 if (have_fw_feat(fw_features, "enabled",
1866 "speculation-policy-favor-security"))
1867 cp->behaviour |= KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY;
1868 if (!have_fw_feat(fw_features, "disabled",
1869 "needs-l1d-flush-msr-pr-0-to-1"))
1870 cp->behaviour |= KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR;
1871 if (!have_fw_feat(fw_features, "disabled",
1872 "needs-spec-barrier-for-bound-checks"))
1873 cp->behaviour |= KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1874 cp->behaviour_mask = KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY |
1875 KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR |
1876 KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1877
1878 of_node_put(fw_features);
1879 }
1880
1881 return 0;
1882}
1883#endif
1884
1762long kvm_arch_vm_ioctl(struct file *filp, 1885long kvm_arch_vm_ioctl(struct file *filp,
1763 unsigned int ioctl, unsigned long arg) 1886 unsigned int ioctl, unsigned long arg)
1764{ 1887{
@@ -1861,6 +1984,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
1861 r = -EFAULT; 1984 r = -EFAULT;
1862 break; 1985 break;
1863 } 1986 }
1987 case KVM_PPC_GET_CPU_CHAR: {
1988 struct kvm_ppc_cpu_char cpuchar;
1989
1990 r = kvmppc_get_cpu_char(&cpuchar);
1991 if (r >= 0 && copy_to_user(argp, &cpuchar, sizeof(cpuchar)))
1992 r = -EFAULT;
1993 break;
1994 }
1864 default: { 1995 default: {
1865 struct kvm *kvm = filp->private_data; 1996 struct kvm *kvm = filp->private_data;
1866 r = kvm->arch.kvm_ops->arch_vm_ioctl(filp, ioctl, arg); 1997 r = kvm->arch.kvm_ops->arch_vm_ioctl(filp, ioctl, arg);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 496e59a2738b..7a99b98cf88e 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -932,6 +932,7 @@ struct kvm_ppc_resize_hpt {
932#define KVM_CAP_HYPERV_SYNIC2 148 932#define KVM_CAP_HYPERV_SYNIC2 148
933#define KVM_CAP_HYPERV_VP_INDEX 149 933#define KVM_CAP_HYPERV_VP_INDEX 149
934#define KVM_CAP_S390_AIS_MIGRATION 150 934#define KVM_CAP_S390_AIS_MIGRATION 150
935#define KVM_CAP_PPC_GET_CPU_CHAR 151
935 936
936#ifdef KVM_CAP_IRQ_ROUTING 937#ifdef KVM_CAP_IRQ_ROUTING
937 938
@@ -1261,6 +1262,8 @@ struct kvm_s390_ucas_mapping {
1261#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg) 1262#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)
1262/* Available with KVM_CAP_PPC_RADIX_MMU */ 1263/* Available with KVM_CAP_PPC_RADIX_MMU */
1263#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info) 1264#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)
1265/* Available with KVM_CAP_PPC_GET_CPU_CHAR */
1266#define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)
1264 1267
1265/* ioctl for vm fd */ 1268/* ioctl for vm fd */
1266#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) 1269#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)