summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/security.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2019-05-16 22:34:35 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2019-05-16 22:34:35 +0200
commit4521d273cfce8afa8a551bc5b9a4aa187fd48c6c (patch)
treee25f3da3f254d4e93967af2ab6d8394d6167a390 /arch/powerpc/kernel/security.c
parent45246ee0499706ca8b16fa03219676ff2958e198 (diff)
parent0f654c12cd720e65f1fb3174a7ee468f1daa09e7 (diff)
Merge 4.4.180 into android-4.4-p
Changes in 4.4.180 kbuild: simplify ld-option implementation KVM: fail KVM_SET_VCPU_EVENTS with invalid exception number cifs: do not attempt cifs operation on smb2+ rename error MIPS: scall64-o32: Fix indirect syscall number load trace: Fix preempt_enable_no_resched() abuse sched/numa: Fix a possible divide-by-zero ceph: ensure d_name stability in ceph_dentry_hash() ceph: fix ci->i_head_snapc leak nfsd: Don't release the callback slot unless it was actually held sunrpc: don't mark uninitialised items as VALID. USB: Add new USB LPM helpers USB: Consolidate LPM checks to avoid enabling LPM twice powerpc/xmon: Add RFI flush related fields to paca dump powerpc/64s: Improve RFI L1-D cache flush fallback powerpc/pseries: Support firmware disable of RFI flush powerpc/powernv: Support firmware disable of RFI flush powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again powerpc/rfi-flush: Always enable fallback flush on pseries powerpc/rfi-flush: Differentiate enabled and patched flush types powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration powerpc: Add security feature flags for Spectre/Meltdown powerpc/pseries: Set or clear security feature flags powerpc/powernv: Set or clear security feature flags powerpc/64s: Move cpu_show_meltdown() powerpc/64s: Enhance the information in cpu_show_meltdown() powerpc/powernv: Use the security flags in pnv_setup_rfi_flush() powerpc/pseries: Use the security flags in pseries_setup_rfi_flush() powerpc/64s: Wire up cpu_show_spectre_v1() powerpc/64s: Wire up cpu_show_spectre_v2() powerpc/pseries: Fix clearing of security feature flags powerpc: Move default security feature flags powerpc/pseries: Restore default security feature flags on setup powerpc/64s: Fix section mismatch warnings from setup_rfi_flush() powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit powerpc/64s: Add barrier_nospec powerpc/64s: Add support for ori barrier_nospec patching powerpc/64s: Patch barrier_nospec in modules powerpc/64s: Enable barrier_nospec based on firmware settings powerpc/64: Use barrier_nospec in syscall entry powerpc: Use barrier_nospec in copy_from_user() powerpc/64s: Enhance the information in cpu_show_spectre_v1() powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2 powerpc/64: Disable the speculation barrier from the command line powerpc/64: Make stf barrier PPC_BOOK3S_64 specific. powerpc/64: Add CONFIG_PPC_BARRIER_NOSPEC powerpc/64: Call setup_barrier_nospec() from setup_arch() powerpc/64: Make meltdown reporting Book3S 64 specific powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E powerpc/asm: Add a patch_site macro & helpers for patching instructions powerpc/64s: Add new security feature flags for count cache flush powerpc/64s: Add support for software count cache flush powerpc/pseries: Query hypervisor for count cache flush settings powerpc/powernv: Query firmware for count cache flush settings powerpc: Avoid code patching freed init sections powerpc/fsl: Add infrastructure to fixup branch predictor flush powerpc/fsl: Add macro to flush the branch predictor powerpc/fsl: Fix spectre_v2 mitigations reporting powerpc/fsl: Add nospectre_v2 command line argument powerpc/fsl: Flush the branch predictor at each kernel entry (64bit) powerpc/fsl: Update Spectre v2 reporting powerpc/security: Fix spectre_v2 reporting powerpc/fsl: Fix the flush of branch predictor. tipc: handle the err returned from cmd header function slip: make slhc_free() silently accept an error pointer intel_th: gth: Fix an off-by-one in output unassigning fs/proc/proc_sysctl.c: Fix a NULL pointer dereference NFS: Forbid setting AF_INET6 to "struct sockaddr_in"->sin_family. netfilter: ebtables: CONFIG_COMPAT: drop a bogus WARN_ON tipc: check bearer name with right length in tipc_nl_compat_bearer_enable tipc: check link name with right length in tipc_nl_compat_link_set bpf: reject wrong sized filters earlier Revert "block/loop: Use global lock for ioctl() operation." ipv4: add sanity checks in ipv4_link_failure() team: fix possible recursive locking when add slaves net: stmmac: move stmmac_check_ether_addr() to driver probe ipv4: set the tcp_min_rtt_wlen range from 0 to one day powerpc/fsl: Enable runtime patching if nospectre_v2 boot arg is used powerpc/fsl: Flush branch predictor when entering KVM powerpc/fsl: Emulate SPRN_BUCSR register powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit) powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit platforms powerpc/fsl: Fixed warning: orphan section `__btb_flush_fixup' powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2 boot arg Documentation: Add nospectre_v1 parameter usbnet: ipheth: prevent TX queue timeouts when device not ready usbnet: ipheth: fix potential null pointer dereference in ipheth_carrier_set qlcnic: Avoid potential NULL pointer dereference netfilter: bridge: set skb transport_header before entering NF_INET_PRE_ROUTING sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init() usb: gadget: net2280: Fix overrun of OUT messages usb: gadget: net2280: Fix net2280_dequeue() usb: gadget: net2272: Fix net2272_dequeue() ARM: dts: pfla02: increase phy reset duration net: ks8851: Dequeue RX packets explicitly net: ks8851: Reassert reset pin if chip ID check fails net: ks8851: Delay requesting IRQ until opened net: ks8851: Set initial carrier state to down net: xilinx: fix possible object reference leak net: ibm: fix possible object reference leak net: ethernet: ti: fix possible object reference leak scsi: qla4xxx: fix a potential NULL pointer dereference usb: u132-hcd: fix resource leak ceph: fix use-after-free on symlink traversal scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN libata: fix using DMA buffers on stack kconfig/[mn]conf: handle backspace (^H) key vfio/type1: Limit DMA mappings per container ALSA: line6: use dynamic buffers ipv4: ip_do_fragment: Preserve skb_iif during fragmentation ipv6/flowlabel: wait rcu grace period before put_pid() ipv6: invert flowlabel sharing check in process and user mode bnxt_en: Improve multicast address setup logic. packet: validate msg_namelen in send directly USB: yurex: Fix protection fault after device removal USB: w1 ds2490: Fix bug caused by improper use of altsetting array USB: core: Fix unterminated string returned by usb_string() USB: core: Fix bug caused by duplicate interface PM usage counter HID: debug: fix race condition with between rdesc_show() and device removal rtc: sh: Fix invalid alarm warning for non-enabled alarm igb: Fix WARN_ONCE on runtime suspend bonding: show full hw address in sysfs for slave entries jffs2: fix use-after-free on symlink traversal debugfs: fix use-after-free on symlink traversal rtc: da9063: set uie_unsupported when relevant vfio/pci: use correct format characters scsi: storvsc: Fix calculation of sub-channel count net: hns: Use NAPI_POLL_WEIGHT for hns driver net: hns: Fix WARNING when remove HNS driver with SMMU enabled hugetlbfs: fix memory leak for resv_map xsysace: Fix error handling in ace_setup ARM: orion: don't use using 64-bit DMA masks ARM: iop: don't use using 64-bit DMA masks usb: usbip: fix isoc packet num validation in get_pipe staging: iio: adt7316: allow adt751x to use internal vref for all dacs staging: iio: adt7316: fix the dac read calculation staging: iio: adt7316: fix the dac write calculation Input: snvs_pwrkey - initialize necessary driver data before enabling IRQ selinux: never allow relabeling on context mounts x86/mce: Improve error message when kernel cannot recover, p2 media: v4l2: i2c: ov7670: Fix PLL bypass register values scsi: libsas: fix a race condition when smp task timeout ASoC:soc-pcm:fix a codec fixup issue in TDM case ASoC: cs4270: Set auto-increment bit for register writes ASoC: tlv320aic32x4: Fix Common Pins perf/x86/intel: Fix handling of wakeup_events for multi-entry PEBS scsi: csiostor: fix missing data copy in csio_scsi_err_handler() iommu/amd: Set exclusion range correctly genirq: Prevent use-after-free and work list corruption usb: dwc3: Fix default lpm_nyet_threshold value scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines Bluetooth: hidp: fix buffer overflow Bluetooth: Align minimum encryption key size for LE and BR/EDR connections UAS: fix alignment of scatter/gather segments ipv6: fix a potential deadlock in do_ipv6_setsockopt() ASoC: Intel: avoid Oops if DMA setup fails timer/debug: Change /proc/timer_stats from 0644 to 0600 netfilter: compat: initialize all fields in xt_init platform/x86: sony-laptop: Fix unintentional fall-through iio: adc: xilinx: fix potential use-after-free on remove HID: input: add mapping for Expose/Overview key HID: input: add mapping for keyboard Brightness Up/Down/Toggle keys libnvdimm/btt: Fix a kmemdup failure check s390/dasd: Fix capacity calculation for large volumes s390/3270: fix lockdep false positive on view->lock KVM: x86: avoid misreporting level-triggered irqs as edge-triggered in tracing tools lib traceevent: Fix missing equality check for strcmp init: initialize jump labels before command line option parsing ipvs: do not schedule icmp errors from tunnels s390: ctcm: fix ctcm_new_device error return code selftests/net: correct the return value for run_netsocktests gpu: ipu-v3: dp: fix CSC handling cw1200: fix missing unlock on error in cw1200_hw_scan() x86/vdso: Pass --eh-frame-hdr to the linker Don't jump to compute_result state from check_result state locking/static_keys: Provide DECLARE and well as DEFINE macros x86/microcode/intel: Add a helper which gives the microcode revision x86: stop exporting msr-index.h to userland bitops: avoid integer overflow in GENMASK(_ULL) x86/microcode/intel: Check microcode revision before updating sibling threads x86/MCE: Save microcode revision in machine check records x86/cpufeatures: Hide AMD-specific speculation flags x86/speculation: Support Enhanced IBRS on future CPUs x86/speculation: Simplify the CPU bug detection logic x86/bugs: Add AMD's variant of SSB_NO x86/bugs: Add AMD's SPEC_CTRL MSR usage x86/bugs: Switch the selection of mitigation from CPU vendor to CPU features locking/atomics, asm-generic: Move some macros from <linux/bitops.h> to a new <linux/bits.h> file x86/bugs: Fix the AMD SSBD usage of the SPEC_CTRL MSR x86/speculation: Remove SPECTRE_V2_IBRS in enum spectre_v2_mitigation x86/microcode: Make sure boot_cpu_data.microcode is up-to-date x86/microcode: Update the new microcode revision unconditionally x86/cpu: Sanitize FAM6_ATOM naming KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled x86/mm: Use WRITE_ONCE() when setting PTEs x86/speculation: Apply IBPB more strictly to avoid cross-process data leak x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation x86/speculation: Propagate information about RSB filling mitigation to sysfs x86/speculation: Update the TIF_SSBD comment x86/speculation: Clean up spectre_v2_parse_cmdline() x86/speculation: Remove unnecessary ret variable in cpu_show_common() x86/speculation: Move STIPB/IBPB string conditionals out of cpu_show_common() x86/speculation: Disable STIBP when enhanced IBRS is in use x86/speculation: Rename SSBD update functions x86/speculation: Reorganize speculation control MSRs update x86/Kconfig: Select SCHED_SMT if SMP enabled sched: Add sched_smt_active() x86/speculation: Rework SMT state change x86/speculation: Reorder the spec_v2 code x86/speculation: Mark string arrays const correctly x86/speculataion: Mark command line parser data __initdata x86/speculation: Unify conditional spectre v2 print functions x86/speculation: Add command line control for indirect branch speculation x86/speculation: Prepare for per task indirect branch speculation control x86/process: Consolidate and simplify switch_to_xtra() code x86/speculation: Avoid __switch_to_xtra() calls x86/speculation: Prepare for conditional IBPB in switch_mm() x86/speculation: Split out TIF update x86/speculation: Prepare arch_smt_update() for PRCTL mode x86/speculation: Prevent stale SPEC_CTRL msr content x86/speculation: Add prctl() control for indirect branch speculation x86/speculation: Enable prctl mode for spectre_v2_user x86/speculation: Add seccomp Spectre v2 user space protection mode x86/speculation: Provide IBPB always command line options kvm: x86: Report STIBP on GET_SUPPORTED_CPUID x86/msr-index: Cleanup bit defines x86/speculation: Consolidate CPU whitelists x86/speculation/mds: Add basic bug infrastructure for MDS x86/speculation/mds: Add BUG_MSBDS_ONLY x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests x86/speculation/mds: Add mds_clear_cpu_buffers() x86/speculation/mds: Clear CPU buffers on exit to user x86/speculation/mds: Conditionally clear CPU buffers on idle entry x86/speculation/mds: Add mitigation control for MDS x86/speculation/l1tf: Document l1tf in sysfs x86/speculation/mds: Add sysfs reporting for MDS x86/speculation/mds: Add mitigation mode VMWERV Documentation: Move L1TF to separate directory Documentation: Add MDS vulnerability documentation x86/cpu/bugs: Use __initconst for 'const' init data x86/speculation: Move arch_smt_update() call to after mitigation decisions x86/speculation/mds: Add SMT warning message x86/speculation/mds: Fix comment x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off cpu/speculation: Add 'mitigations=' cmdline option x86/speculation: Support 'mitigations=' cmdline option x86/speculation/mds: Add 'mitigations=' support for MDS x86/mds: Add MDSUM variant to the MDS documentation Documentation: Correct the possible MDS sysfs values x86/speculation/mds: Fix documentation typo x86/bugs: Change L1TF mitigation string to match upstream USB: serial: use variable for status USB: serial: fix unthrottle races powerpc/64s: Include cpu header bridge: Fix error path for kobject_init_and_add() net: ucc_geth - fix Oops when changing number of buffers in the ring packet: Fix error path in packet_init vlan: disable SIOCSHWTSTAMP in container vrf: sit mtu should not be updated when vrf netdev is the link ipv4: Fix raw socket lookup for local traffic bonding: fix arp_validate toggling in active-backup mode drivers/virt/fsl_hypervisor.c: dereferencing error pointers in ioctl drivers/virt/fsl_hypervisor.c: prevent integer overflow in ioctl powerpc/booke64: set RI in default MSR powerpc/lib: fix book3s/32 boot failure due to code patching Linux 4.4.180 Change-Id: I72f6c596cc992689d95abc8b5d1303d6ec22b051 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'arch/powerpc/kernel/security.c')
-rw-r--r--arch/powerpc/kernel/security.c434
1 files changed, 434 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
new file mode 100644
index 000000000000..fe30ddfd51ee
--- /dev/null
+++ b/arch/powerpc/kernel/security.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Security related flags and so on.
+//
+// Copyright 2018, Michael Ellerman, IBM Corporation.
+
+#include <linux/cpu.h>
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/seq_buf.h>
+
+#include <asm/debug.h>
+#include <asm/asm-prototypes.h>
+#include <asm/code-patching.h>
+#include <asm/security_features.h>
+#include <asm/setup.h>
+
+
+unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
+
+enum count_cache_flush_type {
+ COUNT_CACHE_FLUSH_NONE = 0x1,
+ COUNT_CACHE_FLUSH_SW = 0x2,
+ COUNT_CACHE_FLUSH_HW = 0x4,
+};
+static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
+
+bool barrier_nospec_enabled;
+static bool no_nospec;
+static bool btb_flush_enabled;
+#ifdef CONFIG_PPC_FSL_BOOK3E
+static bool no_spectrev2;
+#endif
+
+static void enable_barrier_nospec(bool enable)
+{
+ barrier_nospec_enabled = enable;
+ do_barrier_nospec_fixups(enable);
+}
+
+void setup_barrier_nospec(void)
+{
+ bool enable;
+
+ /*
+ * It would make sense to check SEC_FTR_SPEC_BAR_ORI31 below as well.
+ * But there's a good reason not to. The two flags we check below are
+ * both are enabled by default in the kernel, so if the hcall is not
+ * functional they will be enabled.
+ * On a system where the host firmware has been updated (so the ori
+ * functions as a barrier), but on which the hypervisor (KVM/Qemu) has
+ * not been updated, we would like to enable the barrier. Dropping the
+ * check for SEC_FTR_SPEC_BAR_ORI31 achieves that. The only downside is
+ * we potentially enable the barrier on systems where the host firmware
+ * is not updated, but that's harmless as it's a no-op.
+ */
+ enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
+ security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR);
+
+ if (!no_nospec)
+ enable_barrier_nospec(enable);
+}
+
+static int __init handle_nospectre_v1(char *p)
+{
+ no_nospec = true;
+
+ return 0;
+}
+early_param("nospectre_v1", handle_nospectre_v1);
+
+#ifdef CONFIG_DEBUG_FS
+static int barrier_nospec_set(void *data, u64 val)
+{
+ switch (val) {
+ case 0:
+ case 1:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!!val == !!barrier_nospec_enabled)
+ return 0;
+
+ enable_barrier_nospec(!!val);
+
+ return 0;
+}
+
+static int barrier_nospec_get(void *data, u64 *val)
+{
+ *val = barrier_nospec_enabled ? 1 : 0;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_barrier_nospec,
+ barrier_nospec_get, barrier_nospec_set, "%llu\n");
+
+static __init int barrier_nospec_debugfs_init(void)
+{
+ debugfs_create_file("barrier_nospec", 0600, powerpc_debugfs_root, NULL,
+ &fops_barrier_nospec);
+ return 0;
+}
+device_initcall(barrier_nospec_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+static int __init handle_nospectre_v2(char *p)
+{
+ no_spectrev2 = true;
+
+ return 0;
+}
+early_param("nospectre_v2", handle_nospectre_v2);
+void setup_spectre_v2(void)
+{
+ if (no_spectrev2)
+ do_btb_flush_fixups();
+ else
+ btb_flush_enabled = true;
+}
+#endif /* CONFIG_PPC_FSL_BOOK3E */
+
+#ifdef CONFIG_PPC_BOOK3S_64
+ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ bool thread_priv;
+
+ thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
+
+ if (rfi_flush || thread_priv) {
+ struct seq_buf s;
+ seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+ seq_buf_printf(&s, "Mitigation: ");
+
+ if (rfi_flush)
+ seq_buf_printf(&s, "RFI Flush");
+
+ if (rfi_flush && thread_priv)
+ seq_buf_printf(&s, ", ");
+
+ if (thread_priv)
+ seq_buf_printf(&s, "L1D private per thread");
+
+ seq_buf_printf(&s, "\n");
+
+ return s.len;
+ }
+
+ if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+ !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
+ return sprintf(buf, "Not affected\n");
+
+ return sprintf(buf, "Vulnerable\n");
+}
+#endif
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct seq_buf s;
+
+ seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+ if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) {
+ if (barrier_nospec_enabled)
+ seq_buf_printf(&s, "Mitigation: __user pointer sanitization");
+ else
+ seq_buf_printf(&s, "Vulnerable");
+
+ if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31))
+ seq_buf_printf(&s, ", ori31 speculation barrier enabled");
+
+ seq_buf_printf(&s, "\n");
+ } else
+ seq_buf_printf(&s, "Not affected\n");
+
+ return s.len;
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct seq_buf s;
+ bool bcs, ccd;
+
+ seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+ bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
+ ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
+
+ if (bcs || ccd) {
+ seq_buf_printf(&s, "Mitigation: ");
+
+ if (bcs)
+ seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
+
+ if (bcs && ccd)
+ seq_buf_printf(&s, ", ");
+
+ if (ccd)
+ seq_buf_printf(&s, "Indirect branch cache disabled");
+ } else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) {
+ seq_buf_printf(&s, "Mitigation: Software count cache flush");
+
+ if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW)
+ seq_buf_printf(&s, " (hardware accelerated)");
+ } else if (btb_flush_enabled) {
+ seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
+ } else {
+ seq_buf_printf(&s, "Vulnerable");
+ }
+
+ seq_buf_printf(&s, "\n");
+
+ return s.len;
+}
+
+#ifdef CONFIG_PPC_BOOK3S_64
+/*
+ * Store-forwarding barrier support.
+ */
+
+static enum stf_barrier_type stf_enabled_flush_types;
+static bool no_stf_barrier;
+bool stf_barrier;
+
+static int __init handle_no_stf_barrier(char *p)
+{
+ pr_info("stf-barrier: disabled on command line.");
+ no_stf_barrier = true;
+ return 0;
+}
+
+early_param("no_stf_barrier", handle_no_stf_barrier);
+
+/* This is the generic flag used by other architectures */
+static int __init handle_ssbd(char *p)
+{
+ if (!p || strncmp(p, "auto", 5) == 0 || strncmp(p, "on", 2) == 0 ) {
+ /* Until firmware tells us, we have the barrier with auto */
+ return 0;
+ } else if (strncmp(p, "off", 3) == 0) {
+ handle_no_stf_barrier(NULL);
+ return 0;
+ } else
+ return 1;
+
+ return 0;
+}
+early_param("spec_store_bypass_disable", handle_ssbd);
+
+/* This is the generic flag used by other architectures */
+static int __init handle_no_ssbd(char *p)
+{
+ handle_no_stf_barrier(NULL);
+ return 0;
+}
+early_param("nospec_store_bypass_disable", handle_no_ssbd);
+
+static void stf_barrier_enable(bool enable)
+{
+ if (enable)
+ do_stf_barrier_fixups(stf_enabled_flush_types);
+ else
+ do_stf_barrier_fixups(STF_BARRIER_NONE);
+
+ stf_barrier = enable;
+}
+
+void setup_stf_barrier(void)
+{
+ enum stf_barrier_type type;
+ bool enable, hv;
+
+ hv = cpu_has_feature(CPU_FTR_HVMODE);
+
+ /* Default to fallback in case fw-features are not available */
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ type = STF_BARRIER_SYNC_ORI;
+ else if (cpu_has_feature(CPU_FTR_ARCH_206))
+ type = STF_BARRIER_FALLBACK;
+ else
+ type = STF_BARRIER_NONE;
+
+ enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
+ (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) ||
+ (security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && hv));
+
+ if (type == STF_BARRIER_FALLBACK) {
+ pr_info("stf-barrier: fallback barrier available\n");
+ } else if (type == STF_BARRIER_SYNC_ORI) {
+ pr_info("stf-barrier: hwsync barrier available\n");
+ } else if (type == STF_BARRIER_EIEIO) {
+ pr_info("stf-barrier: eieio barrier available\n");
+ }
+
+ stf_enabled_flush_types = type;
+
+ if (!no_stf_barrier)
+ stf_barrier_enable(enable);
+}
+
+ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ if (stf_barrier && stf_enabled_flush_types != STF_BARRIER_NONE) {
+ const char *type;
+ switch (stf_enabled_flush_types) {
+ case STF_BARRIER_EIEIO:
+ type = "eieio";
+ break;
+ case STF_BARRIER_SYNC_ORI:
+ type = "hwsync";
+ break;
+ case STF_BARRIER_FALLBACK:
+ type = "fallback";
+ break;
+ default:
+ type = "unknown";
+ }
+ return sprintf(buf, "Mitigation: Kernel entry/exit barrier (%s)\n", type);
+ }
+
+ if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+ !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
+ return sprintf(buf, "Not affected\n");
+
+ return sprintf(buf, "Vulnerable\n");
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int stf_barrier_set(void *data, u64 val)
+{
+ bool enable;
+
+ if (val == 1)
+ enable = true;
+ else if (val == 0)
+ enable = false;
+ else
+ return -EINVAL;
+
+ /* Only do anything if we're changing state */
+ if (enable != stf_barrier)
+ stf_barrier_enable(enable);
+
+ return 0;
+}
+
+static int stf_barrier_get(void *data, u64 *val)
+{
+ *val = stf_barrier ? 1 : 0;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set, "%llu\n");
+
+static __init int stf_barrier_debugfs_init(void)
+{
+ debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, &fops_stf_barrier);
+ return 0;
+}
+device_initcall(stf_barrier_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+
+static void toggle_count_cache_flush(bool enable)
+{
+ if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
+ patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP);
+ count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
+ pr_info("count-cache-flush: software flush disabled.\n");
+ return;
+ }
+
+ patch_branch_site(&patch__call_flush_count_cache,
+ (u64)&flush_count_cache, BRANCH_SET_LINK);
+
+ if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) {
+ count_cache_flush_type = COUNT_CACHE_FLUSH_SW;
+ pr_info("count-cache-flush: full software flush sequence enabled.\n");
+ return;
+ }
+
+ patch_instruction_site(&patch__flush_count_cache_return, PPC_INST_BLR);
+ count_cache_flush_type = COUNT_CACHE_FLUSH_HW;
+ pr_info("count-cache-flush: hardware assisted flush sequence enabled\n");
+}
+
+void setup_count_cache_flush(void)
+{
+ toggle_count_cache_flush(true);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int count_cache_flush_set(void *data, u64 val)
+{
+ bool enable;
+
+ if (val == 1)
+ enable = true;
+ else if (val == 0)
+ enable = false;
+ else
+ return -EINVAL;
+
+ toggle_count_cache_flush(enable);
+
+ return 0;
+}
+
+static int count_cache_flush_get(void *data, u64 *val)
+{
+ if (count_cache_flush_type == COUNT_CACHE_FLUSH_NONE)
+ *val = 0;
+ else
+ *val = 1;
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_count_cache_flush, count_cache_flush_get,
+ count_cache_flush_set, "%llu\n");
+
+static __init int count_cache_flush_debugfs_init(void)
+{
+ debugfs_create_file("count_cache_flush", 0600, powerpc_debugfs_root,
+ NULL, &fops_count_cache_flush);
+ return 0;
+}
+device_initcall(count_cache_flush_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+#endif /* CONFIG_PPC_BOOK3S_64 */