* Re: [PATCH] KVM: PPC: Book3S: Add capabilities for Meltdown/Spectre workarounds
From: Suraj Jitindar Singh @ 2018-01-09 8:28 UTC (permalink / raw)
To: Paul Mackerras, kvm, linuxppc-dev; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20180109044815.GA19326@fergus.ozlabs.ibm.com>
On Tue, 2018-01-09 at 15:48 +1100, Paul Mackerras wrote:
> This adds three new capabilities that give userspace information
> about
> the underlying machine's level of vulnerability to the Meltdown and
> Spectre attacks, and what instructions the hardware implements to
> assist software to work around the vulnerabilities.
>
> Each capability is a tri-state, where 0 indicates that the machine is
> vulnerable and no workarounds are implement, 1 indicates that the
> machine is vulnerable but workaround assist instructions are
> available, and 2 indicates that the machine is not vulnerable.
>
> The capabilities are:
>
> KVM_CAP_PPC_SAFE_CACHE reports the vulnerability of the machine to
> attacks based on using speculative loads to data in L1 cache which
> should not be addressable. The workaround provided by hardware is an
> instruction to invalidate the entire L1 data cache.
>
> KVM_CAP_PPC_SAFE_BOUNDS_CHECK reports the vulnerability of the
> machine
> to attacks based on using speculative loads behind mispredicted
> bounds
> checks. The workaround provided by hardware is an instruction that
> acts as a speculation barrier.
>
> KVM_CAP_PPC_SAFE_INDIRECT_BRANCH reports the vulnerability of the
> machine to attacks based on poisoning the indirect branch predictor.
> No workaround that requires software changes is provided; the current
> hardware fix is to prevent speculation past indirect branches.
>
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
> ---
> Note: This patch depends on the patch "powerpc/pseries: Add
> H_GET_CPU_CHARACTERISTICS flags & wrapper" by Michael Ellerman,
> available at http://patchwork.ozlabs.org/patch/856914/ .
>
> Documentation/virtual/kvm/api.txt | 36 +++++++
> arch/powerpc/kvm/powerpc.c | 202
> ++++++++++++++++++++++++++++++++++++++
> include/uapi/linux/kvm.h | 3 +
> 3 files changed, 241 insertions(+)
>
> diff --git a/Documentation/virtual/kvm/api.txt
> b/Documentation/virtual/kvm/api.txt
> index 57d3ee9..8d76260 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -4369,3 +4369,39 @@ Parameters: none
> This capability indicates if the flic device will be able to get/set
> the
> AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and
> allows
> to discover this without having to create a flic device.
> +
> +8.14 KVM_CAP_PPC_SAFE_CACHE
> +
> +Architectures: ppc
> +
> +This capability gives information about the underlying machine's
> +vulnerability or otherwise to the Meltdown attack. Its value is a
> +tristate, where 0 indicates the machine is vulnerable, 1 indicates
> the
> +hardware is vulnerable but provides assistance to work around the
> +vulnerability (specifically by providing a fast L1 data cache flush
> +facility), and 2 indicates that the machine is not vulnerable.
> +
> +8.15 KVM_CAP_PPC_SAFE_BOUNDS_CHECK
> +
> +Architectures: ppc
> +
> +This capability gives information about the underlying machine's
> +vulnerability or otherwise to the bounds-check variant of the
> Spectre
> +attack. Its value is a tristate, where 0 indicates the machine is
> +vulnerable, 1 indicates the hardware is vulnerable but provides
> +assistance to work around the vulnerability (specifically by
> providing
> +an instruction that acts as a speculation barrier), and 2 indicates
> +that the machine is not vulnerable.
> +
> +8.16 KVM_CAP_PPC_SAFE_INDIRECT_BRANCH
> +
> +Architectures: ppc
> +
> +This capability gives information about the underlying machine's
> +vulnerability or otherwise to the indirect branch variant of the
> Spectre
> +attack. Its value is a tristate, where 0 indicates the machine is
> +vulnerable and 2 indicates that the machine is not vulnerable.
> +(1 would indicate the availability of a workaround that software
> +needs to implement, but there is currently no workaround that needs
> +software changes.)
> +
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 1915e86..58e863b 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -39,6 +39,10 @@
> #include <asm/iommu.h>
> #include <asm/switch_to.h>
> #include <asm/xive.h>
> +#ifdef CONFIG_PPC_PSERIES
> +#include <asm/hvcall.h>
> +#include <asm/plpar_wrappers.h>
> +#endif
>
> #include "timing.h"
> #include "irq.h"
> @@ -488,6 +492,193 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
> module_put(kvm->arch.kvm_ops->owner);
> }
>
> +#ifdef CONFIG_PPC_BOOK3S_64
> +/*
> + * These functions check whether the underlying hardware is safe
> + * against the Meltdown/Spectre attacks and whether it supplies
> + * instructions for use in workarounds. The information comes from
> + * firmware, either via the device tree on powernv platforms or
> + * from an hcall on pseries platforms.
> + *
> + * For check_safe_cache() and check_safe_bounds_check(), a return
> + * value of 0 means vulnerable, 1 means vulnerable but workaround
> + * instructions are provided, and 2 means not vulnerable (no
> workaround
> + * is needed).
> + * For check_safe_indirect_branch(), 0 means vulnerable and 2 means
> + * not vulnerable.
> + */
> +static inline bool have_fw_feat(struct device_node *fw_features,
> + const char *state, const char *name)
> +{
> + struct device_node *np;
> + bool r = false;
> +
> + np = of_get_child_by_name(fw_features, name);
> + if (np) {
> + r = of_property_read_bool(np, state);
> + of_node_put(np);
> + }
> + return r;
> +}
> +
> +#ifdef CONFIG_PPC_PSERIES
> +static bool check_pseries_safe_cache(int *rp)
> +{
> + struct h_cpu_char_result c;
> + unsigned long rc;
> + int r = 0;
> +
> + if (!machine_is(pseries))
> + return false;
> +
> + rc = plpar_get_cpu_characteristics(&c);
> + if (rc == H_SUCCESS) {
> + if (!(c.behavior &
> H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV))
s/H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV/H_CPU_BEHAV_L1D_FLUSH_PR
> + r = 2;
> + else if ((c.character &
> H_GET_CPU_CHAR_CHAR_L1D_PRIVATE) &&
s/H_GET_CPU_CHAR_CHAR_L1D_PRIVATE/H_CPU_CHAR_L1D_THREAD_PRIV
> + ((c.character &
> H_GET_CPU_CHAR_CHAR_ORI30_L1_FLUSH) ||
s/H_GET_CPU_CHAR_CHAR_ORI30_L1_FLUSH/H_CPU_CHAR_L1D_FLUSH_ORI30
> + (c.character &
> H_GET_CPU_CHAR_CHAR_MTTRIG2_L1_FLUSH)))
s/H_GET_CPU_CHAR_CHAR_MTTRIG2_L1_FLUSH/H_CPU_CHAR_L1D_FLUSH_TRIG2
etc.
> + r = 1;
> + }
> + *rp = r;
> + return true;
> +}
> +
> +static bool check_pseries_safe_bounds_check(int *rp)
> +{
> + struct h_cpu_char_result c;
> + unsigned long rc;
> + int r = 0;
> +
> + if (!machine_is(pseries))
> + return false;
> +
> + rc = plpar_get_cpu_characteristics(&c);
> + if (rc == H_SUCCESS) {
> + if (!(c.behavior &
> H_GET_CPU_CHAR_BEHAV_SPEC_BAR_BNDS_CHK))
> + r = 2;
> + else if (c.character &
> H_GET_CPU_CHAR_CHAR_ORI31_SPEC_BAR)
> + r = 1;
> + }
> + *rp = r;
> + return true;
> +}
> +
> +static bool check_pseries_safe_indirect_branch(int *rp)
> +{
> + struct h_cpu_char_result c;
> + unsigned long rc;
> + int r = 0;
> +
> + if (!machine_is(pseries))
> + return false;
> +
> + rc = plpar_get_cpu_characteristics(&c);
> + if (rc == H_SUCCESS) {
> + if (c.character & H_GET_CPU_CHAR_CHAR_BCCTR_SERIAL)
> + r = 2;
> + }
> + *rp = r;
> + return true;
> +}
> +
> +#else
> +static bool check_pseries_safe_cache(int *rp)
> +{
> + return false;
> +}
> +
> +static bool check_pseries_safe_bounds_check(int *rp)
> +{
> + return false;
> +}
> +
> +static bool check_pseries_safe_indirect_branch(int *rp)
> +{
> + return false;
> +}
> +#endif
> +
> +static int check_safe_cache(void)
> +{
> + struct device_node *np, *fw_features;
> + int r = 0;
> +
> + if (check_pseries_safe_cache(&r))
> + return r;
> +
> + np = of_find_node_by_name(NULL, "ibm,opal");
> + if (np) {
> + fw_features = of_get_child_by_name(np, "fw-
> features");
> + of_node_put(np);
> + if (!fw_features)
> + return 0;
> + if (have_fw_feat(fw_features, "disabled",
> + "needs-l1d-flush-msr-pr-0-to-1"))
> + r = 2;
> + else if (have_fw_feat(fw_features, "enabled",
> + "fw-l1d-thread-split") &&
> + (have_fw_feat(fw_features, "enabled",
> + "inst-l1d-flush-trig2") ||
> + have_fw_feat(fw_features, "enabled",
> + "inst-l1d-flush-
> ori30,30,0")))
> + r = 1;
> + of_node_put(fw_features);
> + }
> +
> + return r;
> +}
> +
> +static int check_safe_bounds_check(void)
> +{
> + struct device_node *np, *fw_features;
> + int r = 0;
> +
> + if (check_pseries_safe_bounds_check(&r))
> + return r;
> +
> + np = of_find_node_by_name(NULL, "ibm,opal");
> + if (np) {
> + fw_features = of_get_child_by_name(np, "fw-
> features");
> + of_node_put(np);
> + if (!fw_features)
> + return 0;
> + if (have_fw_feat(fw_features, "disabled",
> + "needs-spec-barrier-for-bound-
> checks"))
> + r = 2;
> + else if (have_fw_feat(fw_features, "enabled",
> + "inst-spec-barrier-
> ori31,31,0"))
> + r = 1;
> + of_node_put(fw_features);
> + }
> +
> + return r;
> +}
> +
> +static int check_safe_indirect_branch(void)
> +{
> + struct device_node *np, *fw_features;
> + int r = 0;
> +
> + if (check_pseries_safe_indirect_branch(&r))
> + return r;
> +
> + np = of_find_node_by_name(NULL, "ibm,opal");
> + if (np) {
> + fw_features = of_get_child_by_name(np, "fw-
> features");
> + of_node_put(np);
> + if (!fw_features)
> + return 0;
> + if (have_fw_feat(fw_features, "enabled",
> + "fw-bcctrl-serialized"))
> + r = 2;
> + of_node_put(fw_features);
> + }
> +
> + return r;
> +}
> +#endif
> +
> int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> {
> int r;
> @@ -646,6 +837,17 @@ int kvm_vm_ioctl_check_extension(struct kvm
> *kvm, long ext)
> r = hv_enabled &&
> (cur_cpu_spec->cpu_user_features2 &
> PPC_FEATURE2_HTM_COMP);
> break;
> +#ifdef CONFIG_PPC_BOOK3S_64
> + case KVM_CAP_PPC_SAFE_CACHE:
> + r = check_safe_cache();
> + break;
> + case KVM_CAP_PPC_SAFE_BOUNDS_CHECK:
> + r = check_safe_bounds_check();
> + break;
> + case KVM_CAP_PPC_SAFE_INDIRECT_BRANCH:
> + r = check_safe_indirect_branch();
> + break;
> +#endif
> default:
> r = 0;
> break;
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 496e59a..0a480e9 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -932,6 +932,9 @@ struct kvm_ppc_resize_hpt {
> #define KVM_CAP_HYPERV_SYNIC2 148
> #define KVM_CAP_HYPERV_VP_INDEX 149
> #define KVM_CAP_S390_AIS_MIGRATION 150
> +#define KVM_CAP_PPC_SAFE_CACHE 151
> +#define KVM_CAP_PPC_SAFE_BOUNDS_CHECK 152
> +#define KVM_CAP_PPC_SAFE_INDIRECT_BRANCH 153
>
> #ifdef KVM_CAP_IRQ_ROUTING
>
^ permalink raw reply
* Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs
From: Jon Masters @ 2018-01-09 8:11 UTC (permalink / raw)
To: Greg KH
Cc: Michael Ellerman, Thomas Gleixner, mikey, Peter Zijlstra, LKML,
npiggin, linuxppc-dev, oohall, Anton Blanchard, Paul Mackerras
In-Reply-To: <20180109080527.GA32120@kroah.com>
On 01/09/2018 03:05 AM, Greg KH wrote:
> On Tue, Jan 09, 2018 at 01:06:23AM -0500, Jon Masters wrote:
>> Knowing that the IBM team was going to post with this sysfs interface,
>> our trees contain the rfi_flush file. I mentioned it to some folks on
>> this end (because we know we don't want to add things in sysfs
>> generally, debugfs is a good substitute, per Andrea, and I raised this
>> with him yesterday as a concern in the backport here) but in the end it
>> seemed reasonable to pull this in because it was what got posted, and as
>> Michael says, it's gone into other distro kernels beyond just ours.
>
> What distro kernels end up enabling does not really reflect on what we
> end up doing in mainline. The api for this should NOT be arch-specific
> if at all possible, that way lies madness. Do you want to write
> userspace tools to handle the 60+ different arch implementations?
>
> Don't let the fragmentation problems of the period in which no one was
> allowed to talk to each other, result in a unchangable mess, that would
> be insane.
Totally fine :) Just saying we tried to do reasonable things with what
we had. Whatever happens upstream in the end is, of course, what we'll
make sure fits into updates that go into the likes of RHEL.
Jon.
--
Computer Architect | Sent from my Fedora powered laptop
^ permalink raw reply
* Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs
From: Greg KH @ 2018-01-09 8:05 UTC (permalink / raw)
To: Jon Masters
Cc: Michael Ellerman, Thomas Gleixner, mikey, Peter Zijlstra, LKML,
npiggin, linuxppc-dev, oohall, Anton Blanchard, Paul Mackerras
In-Reply-To: <f4a66b7c-0ee0-07da-b327-42ba6a8c704b@redhat.com>
On Tue, Jan 09, 2018 at 01:06:23AM -0500, Jon Masters wrote:
> Knowing that the IBM team was going to post with this sysfs interface,
> our trees contain the rfi_flush file. I mentioned it to some folks on
> this end (because we know we don't want to add things in sysfs
> generally, debugfs is a good substitute, per Andrea, and I raised this
> with him yesterday as a concern in the backport here) but in the end it
> seemed reasonable to pull this in because it was what got posted, and as
> Michael says, it's gone into other distro kernels beyond just ours.
What distro kernels end up enabling does not really reflect on what we
end up doing in mainline. The api for this should NOT be arch-specific
if at all possible, that way lies madness. Do you want to write
userspace tools to handle the 60+ different arch implementations?
Don't let the fragmentation problems of the period in which no one was
allowed to talk to each other, result in a unchangable mess, that would
be insane.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs
From: Greg KH @ 2018-01-09 8:03 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, linux-kernel, tglx, peterz, npiggin, anton, mikey,
oohall, paulus
In-Reply-To: <20180108165453.26066-9-mpe@ellerman.id.au>
On Tue, Jan 09, 2018 at 03:54:51AM +1100, Michael Ellerman wrote:
> From: Nicholas Piggin <npiggin@gmail.com>
>
> Expose the state of the RFI flush (enabled/disabled) via sysfs, and
> allow it to be enabled/dissabled at runtime.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/kernel/setup.h | 2 ++
> arch/powerpc/kernel/sysfs.c | 41 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 43 insertions(+)
You forgot a Documentation/ABI/ update for a new sysfs file :(
> diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
> index 21c18071d9d5..493b03b0a966 100644
> --- a/arch/powerpc/kernel/setup.h
> +++ b/arch/powerpc/kernel/setup.h
> @@ -61,4 +61,6 @@ void kvm_cma_reserve(void);
> static inline void kvm_cma_reserve(void) { };
> #endif
>
> +extern bool rfi_flush;
> +
> #endif /* __ARCH_POWERPC_KERNEL_SETUP_H */
> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
> index b8d4a1dac39f..8c19d014cffc 100644
> --- a/arch/powerpc/kernel/sysfs.c
> +++ b/arch/powerpc/kernel/sysfs.c
> @@ -20,6 +20,7 @@
> #include <asm/firmware.h>
>
> #include "cacheinfo.h"
> +#include "setup.h"
>
> #ifdef CONFIG_PPC64
> #include <asm/paca.h>
> @@ -496,6 +497,43 @@ static DEVICE_ATTR(spurr, 0400, show_spurr, NULL);
> static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
> static DEVICE_ATTR(pir, 0400, show_pir, NULL);
>
> +#ifdef CONFIG_PPC_BOOK3S_64
> +static ssize_t show_rfi_flush(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%d\n", rfi_flush ? 1 : 0);
> +}
> +
> +static ssize_t __used store_rfi_flush(struct device *dev,
> + struct device_attribute *attr, const char *buf,
> + size_t count)
> +{
> + int val;
> + int ret = 0;
> +
> + ret = sscanf(buf, "%d", &val);
> + if (ret != 1)
> + return -EINVAL;
> +
> + if (val == 1)
> + rfi_flush_enable(true);
> + else if (val == 0)
> + rfi_flush_enable(false);
> + else
> + return -EINVAL;
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR(rfi_flush, 0600,
> + show_rfi_flush, store_rfi_flush);
DEVICE_ATTR_RW()? And why 0600? That's odd.
> +
> +static void sysfs_create_rfi_flush(void)
> +{
> + device_create_file(cpu_subsys.dev_root, &dev_attr_rfi_flush);
No error checking?
And as Thomas said, why not just use the generic infrastructure he
created instead? That way there is some form of unity here for the same
exact issue.
At least he documented the api :)
thanks,
greg k-h
^ permalink raw reply
* Re: Sleep in preempt_disable on powernv with 'cat /proc/cpuinfo' on v4.15
From: Benjamin Herrenschmidt @ 2018-01-09 7:43 UTC (permalink / raw)
To: John Sperbeck, Shriya, Michael Ellerman, linuxppc-dev
In-Reply-To: <CAFNjLiW4Dc9J_Q6L0zOT1f+AyNYOLWFPk1iXb7JNTPaqpozkCQ@mail.gmail.com>
On Mon, 2018-01-08 at 21:30 -0800, John Sperbeck wrote:
> The pnv_get_proc_freq() function was recently changed to call
> cpufreq_get(), instead of cpufreq_quick_get(), in order to fetch
> a more up-to-date value for the CPU frequency:
>
> cd77b5ce208c153260ed7882d8910f2395bfaabd
> powerpc/powernv/cpufreq: Fix the frequency read by /proc/cpuinfo
>
> Unfortunately, this function is called from show_cpuinfo() in
> arch/powerpc/kernel/setup-common.c with preemption disabled. The
> cpufreq_get() function might do a down_read(), which can sleep.
>
> With CONFIG_DEBUG_KERNEL and CONFIG_DEBUG_ATOMIC_SLEEP set, a warning
> like the following is generated when running 'cat /proc/cpuinfo':
We could just either remove the preempt_disable completely like
x86 and keep it racy, or stick a cpus_read_lock around it. I dont think
we need that preempt_disable, it's definitely overkill.
Michael, what do you think ? I'm keen on sync'ing with x86 here...
Cheers,
Ben.
> BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:23
> in_atomic(): 1, irqs_disabled(): 0, pid: 16939, name: cat
> CPU: 33 PID: 16939 Comm: cat Tainted: G W 4.15.0-smp-DEV #1
> Call Trace:
> [c000000fef07bab0] [c000000000a32c30] dump_stack+0xb0/0xf0 (unreliable)
> [c000000fef07baf0] [c0000000001343a8] ___might_sleep+0x178/0x1b0
> [c000000fef07bb70] [c000000000a50f58] down_read+0x38/0x90
> [c000000fef07bba0] [c0000000008287d0] cpufreq_get+0x50/0xc0
> [c000000fef07bbf0] [c000000000097a08] pnv_get_proc_freq+0x28/0x60
> [c000000fef07bc20] [c00000000002c554] show_cpuinfo+0x194/0x450
> [c000000fef07bcb0] [c00000000039c848] seq_read+0x1f8/0x590
> [c000000fef07bd40] [c00000000040d1d4] proc_reg_read+0xb4/0x180
> [c000000fef07bd90] [c00000000035d6a0] vfs_read+0x100/0x220
> [c000000fef07bde0] [c00000000035dc6c] SyS_read+0x6c/0x110
> [c000000fef07be30] [c00000000000b220] system_call+0x58/0x6c
>
^ permalink raw reply
* Re: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache
From: Joel Stanley @ 2018-01-09 7:02 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Michael Neuling, peterz, Linux Kernel Mailing List,
npiggin, Oliver O'Halloran, Anton Blanchard, Paul Mackerras,
Thomas Gleixner
In-Reply-To: <20180108165453.26066-7-mpe@ellerman.id.au>
On Mon, Jan 8, 2018 at 8:54 AM, Michael Ellerman <mpe@ellerman.id.au> wrote:
> On some CPUs we can prevent the Meltdown vulnerability by flushing the
> L1-D cache on exit from kernel to user mode, and from hypervisor to
> guest.
Super minor nitpicks below. Don't let this hold up your work.
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1449,6 +1449,88 @@ masked_##_H##interrupt: \
> b .; \
> MASKED_DEC_HANDLER(_H)
>
> +TRAMP_REAL_BEGIN(rfi_flush_fallback)
> + SET_SCRATCH0(r13);
> + GET_PACA(r13);
> + std r9,PACA_EXRFI+EX_R9(r13)
> + std r10,PACA_EXRFI+EX_R10(r13)
> + std r11,PACA_EXRFI+EX_R11(r13)
> + std r12,PACA_EXRFI+EX_R12(r13)
> + std r8,PACA_EXRFI+EX_R13(r13)
> + mfctr r9
> + ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
> + ld r11,PACA_L1D_FLUSH_SETS(r13)
> + ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
> + /*
> + * The load adresses are at staggered offsets within cachelines,
> + * which suits some pipelines better (on others it should not
> + * hurt.
Nit: missing ) on the last line.
> + */
> + addi r12,r12,8
> + mtctr r11
> + DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
> +
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
> }
> }
>
> +#ifdef CONFIG_PPC_BOOK3S_64
> +void do_rfi_flush_fixups(enum l1d_flush_type types)
> +{
> + unsigned int instrs[3], *dest;
> + long *start, *end;
> + int i;
> +
> + start = PTRRELOC(&__start___rfi_flush_fixup),
> + end = PTRRELOC(&__stop___rfi_flush_fixup);
> +
> + instrs[0] = 0x60000000; /* nop */
> + instrs[1] = 0x60000000; /* nop */
> + instrs[2] = 0x60000000; /* nop */
> +
> + if (types & L1D_FLUSH_FALLBACK)
This looked a bit confusing on first read. Do we ever get
L1D_FLUSH_FALLBACK and the other types? If not, could it be made
clearer?
if ( types & L1D_FLUSH_FALLBACK)
/* stuff */
else
/* other types */
> + /* b .+16 to fallback flush */
> + instrs[0] = 0x48000010;
> +
> + i = 0;
> + if (types & L1D_FLUSH_ORI) {
> + instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
> + instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/
> + }
> +
> + if (types & L1D_FLUSH_MTTRIG)
> + instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */
> +
> + for (i = 0; start < end; start++, i++) {
> + dest = (void *)start + *start;
> +
> + pr_devel("patching dest %lx\n", (unsigned long)dest);
> +
> + patch_instruction(dest, instrs[0]);
> + patch_instruction(dest + 1, instrs[1]);
> + patch_instruction(dest + 2, instrs[2]);
> + }
> +
> + printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
> +}
> +#endif /* CONFIG_PPC_BOOK3S_64 */
> +
> void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
> {
> long *start, *end;
> --
> 2.14.3
>
^ permalink raw reply
* [PATCH] powerpc/32: Remove memory clobber asm constraint on dcbX() functions
From: Christophe Leroy @ 2018-01-09 6:57 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Scott Wood
Cc: linux-kernel, linuxppc-dev
Instead of just telling GCC that dcbz(), dcbi(), dcbf() and dcbst()
clobber memory, tell it what it clobbers:
* dcbz(), dcbi() and dcbf() clobbers one cacheline as output
* dcbf() and dcbst() clobbers one cacheline as input
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/cache.h | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index c1d257aa4c2d..fc8fe18acf8c 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -82,22 +82,31 @@ extern void _set_L3CR(unsigned long);
static inline void dcbz(void *addr)
{
- __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory");
+ __asm__ __volatile__ ("dcbz 0, %1" :
+ "=m"(*(char (*)[L1_CACHE_BYTES])addr) :
+ "r"(addr) :);
}
static inline void dcbi(void *addr)
{
- __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory");
+ __asm__ __volatile__ ("dcbi 0, %1" :
+ "=m"(*(char (*)[L1_CACHE_BYTES])addr) :
+ "r"(addr) :);
}
static inline void dcbf(void *addr)
{
- __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory");
+ __asm__ __volatile__ ("dcbf 0, %1" :
+ "=m"(*(char (*)[L1_CACHE_BYTES])addr) :
+ "r"(addr), "m"(*(char (*)[L1_CACHE_BYTES])addr) :
+ );
}
static inline void dcbst(void *addr)
{
- __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory");
+ __asm__ __volatile__ ("dcbst 0, %0" : :
+ "r"(addr), "m"(*(char (*)[L1_CACHE_BYTES])addr) :
+ );
}
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
--
2.13.3
^ permalink raw reply related
* Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs
From: Jon Masters @ 2018-01-09 6:06 UTC (permalink / raw)
To: Michael Ellerman, Thomas Gleixner
Cc: mikey, Peter Zijlstra, Greg KH, LKML, npiggin, linuxppc-dev,
oohall, Anton Blanchard, Paul Mackerras
In-Reply-To: <87y3l880js.fsf@concordia.ellerman.id.au>
On 01/08/2018 05:09 PM, Michael Ellerman wrote:
> Thomas Gleixner <tglx@linutronix.de> writes:
>
>> On Tue, 9 Jan 2018, Michael Ellerman wrote:
>>
>> Sorry, I wasn't aware about your efforts and did not cc you. I've just
>> queued a more generic sysfs interface for this whole mess:
>
> No worries.
>
>> https://lkml.kernel.org/r/20180107214913.096657732@linutronix.de
>>
>> It should be simple to extend for write and it would be great if all
>> affected architectures could share it.
>
> As you say this has all been a bit of a mess
Indeed. All of us wish this went very differently.
I've been testing various versions of these patches since before the
holidays. For those doing backports to older kernels, a note that the
IBM team added OOL (Out Of Line) exception handlers and reworked all of
that code over the years since older kernels (e.g. 3.10) so you might
get problems on those if you enable the debug entry. I've got notes on
how to backport the OOL exceptions to older kernels if anyone cares.
> and as a result we already have people running kernels with this patch,
> so we don't want to remove the 'rfi_flush' file.
Knowing that the IBM team was going to post with this sysfs interface,
our trees contain the rfi_flush file. I mentioned it to some folks on
this end (because we know we don't want to add things in sysfs
generally, debugfs is a good substitute, per Andrea, and I raised this
with him yesterday as a concern in the backport here) but in the end it
seemed reasonable to pull this in because it was what got posted, and as
Michael says, it's gone into other distro kernels beyond just ours.
> But we will certainly add support on powerpc for the files you have
> created, in addition to 'rfi_flush'.
Thanks,
Jon.
--
Computer Architect | Sent from my Fedora powered laptop
^ permalink raw reply
* Re: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache
From: Jon Masters @ 2018-01-09 5:55 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20180108165453.26066-7-mpe@ellerman.id.au>
On 01/08/2018 11:54 AM, Michael Ellerman wrote:
> On some CPUs we can prevent the Meltdown vulnerability by flushing the
> L1-D cache on exit from kernel to user mode, and from hypervisor to
> guest.
I've tested multiple iterations of these patches over the past few
weeks, on both real hardware, and on a variety of emulation platforms.
Tested-by: Jon Masters <jcm@redhat.com>
--
Computer Architect | Sent from my Fedora powered laptop
^ permalink raw reply
* [PATCH kernel] powerpc/lpar/debug: Initialize flags before printing debug message
From: Alexey Kardashevskiy @ 2018-01-09 5:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexey Kardashevskiy
With enabled DEBUG, there is a compile error:
"error: ‘flags’ is used uninitialized in this function".
This moves pr_devel() little further where @flags are initialized.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
/home/aik/p/guest-kernel/arch/powerpc/platforms/pseries/lpar.c: In function ‘pSeries_lpar_hpte_updatepp’:
/home/aik/p/guest-kernel/include/linux/printk.h:320:2: error: ‘flags’ is used uninitialized in this function [-Werror=un
initialized]
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
^
/home/aik/p/guest-kernel/arch/powerpc/platforms/pseries/lpar.c:304:16: note: ‘flags’ was declared here
unsigned long flags;
^
---
arch/powerpc/platforms/pseries/lpar.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 0ee4a46..1365424 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -306,14 +306,14 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
want_v = hpte_encode_avpn(vpn, psize, ssize);
+ flags = (newpp & 7) | H_AVPN;
+ if (mmu_has_feature(MMU_FTR_KERNEL_RO))
+ /* Move pp0 into bit 8 (IBM 55) */
+ flags |= (newpp & HPTE_R_PP0) >> 55;
+
pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
want_v, slot, flags, psize);
- flags = (newpp & 7) | H_AVPN;
- if (mmu_has_feature(MMU_FTR_KERNEL_RO))
- /* Move pp0 into bit 8 (IBM 55) */
- flags |= (newpp & HPTE_R_PP0) >> 55;
-
lpar_rc = plpar_pte_protect(flags, slot, want_v);
if (lpar_rc == H_NOT_FOUND) {
--
2.11.0
^ permalink raw reply related
* [PATCH kernel] powerpc/init: Do not advertise radix during client-architecture-support
From: Alexey Kardashevskiy @ 2018-01-09 5:45 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexey Kardashevskiy
Currently the pseries kernel advertises radix MMU support even if
the actual support is disabled via the CONFIG_PPC_RADIX_MMU option.
This adds a check for CONFIG_PPC_RADIX_MMU to avoid advertising radix
to the hypervisor.
Suggested-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
arch/powerpc/kernel/prom_init.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 02190e9..65879df 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1109,7 +1109,8 @@ static void __init prom_check_platform_support(void)
}
}
- if (supported.radix_mmu && supported.radix_gtse) {
+ if (supported.radix_mmu && supported.radix_gtse &&
+ IS_ENABLED(CONFIG_PPC_RADIX_MMU)) {
/* Radix preferred - but we require GTSE for now */
prom_debug("Asking for radix with GTSE\n");
ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
--
2.11.0
^ permalink raw reply related
* Sleep in preempt_disable on powernv with 'cat /proc/cpuinfo' on v4.15
From: John Sperbeck @ 2018-01-09 5:30 UTC (permalink / raw)
To: Shriya, Michael Ellerman, Benjamin Herrenschmidt, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1585 bytes --]
The pnv_get_proc_freq() function was recently changed to call
cpufreq_get(), instead of cpufreq_quick_get(), in order to fetch
a more up-to-date value for the CPU frequency:
cd77b5ce208c153260ed7882d8910f2395bfaabd
powerpc/powernv/cpufreq: Fix the frequency read by /proc/cpuinfo
Unfortunately, this function is called from show_cpuinfo() in
arch/powerpc/kernel/setup-common.c with preemption disabled. The
cpufreq_get() function might do a down_read(), which can sleep.
With CONFIG_DEBUG_KERNEL and CONFIG_DEBUG_ATOMIC_SLEEP set, a warning
like the following is generated when running 'cat /proc/cpuinfo':
BUG: sleeping function called from invalid context at
kernel/locking/rwsem.c:23
in_atomic(): 1, irqs_disabled(): 0, pid: 16939, name: cat
CPU: 33 PID: 16939 Comm: cat Tainted: G W 4.15.0-smp-DEV
#1
Call Trace:
[c000000fef07bab0] [c000000000a32c30] dump_stack+0xb0/0xf0 (unreliable)
[c000000fef07baf0] [c0000000001343a8] ___might_sleep+0x178/0x1b0
[c000000fef07bb70] [c000000000a50f58] down_read+0x38/0x90
[c000000fef07bba0] [c0000000008287d0] cpufreq_get+0x50/0xc0
[c000000fef07bbf0] [c000000000097a08] pnv_get_proc_freq+0x28/0x60
[c000000fef07bc20] [c00000000002c554] show_cpuinfo+0x194/0x450
[c000000fef07bcb0] [c00000000039c848] seq_read+0x1f8/0x590
[c000000fef07bd40] [c00000000040d1d4] proc_reg_read+0xb4/0x180
[c000000fef07bd90] [c00000000035d6a0] vfs_read+0x100/0x220
[c000000fef07bde0] [c00000000035dc6c] SyS_read+0x6c/0x110
[c000000fef07be30] [c00000000000b220] system_call+0x58/0x6c
[-- Attachment #2: Type: text/html, Size: 1761 bytes --]
^ permalink raw reply
* [PATCH] KVM: PPC: Book3S: Add capabilities for Meltdown/Spectre workarounds
From: Paul Mackerras @ 2018-01-09 4:48 UTC (permalink / raw)
To: kvm, linuxppc-dev; +Cc: kvm-ppc, David Gibson, Suraj Jitindar Singh
This adds three new capabilities that give userspace information about
the underlying machine's level of vulnerability to the Meltdown and
Spectre attacks, and what instructions the hardware implements to
assist software to work around the vulnerabilities.
Each capability is a tri-state, where 0 indicates that the machine is
vulnerable and no workarounds are implement, 1 indicates that the
machine is vulnerable but workaround assist instructions are
available, and 2 indicates that the machine is not vulnerable.
The capabilities are:
KVM_CAP_PPC_SAFE_CACHE reports the vulnerability of the machine to
attacks based on using speculative loads to data in L1 cache which
should not be addressable. The workaround provided by hardware is an
instruction to invalidate the entire L1 data cache.
KVM_CAP_PPC_SAFE_BOUNDS_CHECK reports the vulnerability of the machine
to attacks based on using speculative loads behind mispredicted bounds
checks. The workaround provided by hardware is an instruction that
acts as a speculation barrier.
KVM_CAP_PPC_SAFE_INDIRECT_BRANCH reports the vulnerability of the
machine to attacks based on poisoning the indirect branch predictor.
No workaround that requires software changes is provided; the current
hardware fix is to prevent speculation past indirect branches.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
Note: This patch depends on the patch "powerpc/pseries: Add
H_GET_CPU_CHARACTERISTICS flags & wrapper" by Michael Ellerman,
available at http://patchwork.ozlabs.org/patch/856914/ .
Documentation/virtual/kvm/api.txt | 36 +++++++
arch/powerpc/kvm/powerpc.c | 202 ++++++++++++++++++++++++++++++++++++++
include/uapi/linux/kvm.h | 3 +
3 files changed, 241 insertions(+)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 57d3ee9..8d76260 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4369,3 +4369,39 @@ Parameters: none
This capability indicates if the flic device will be able to get/set the
AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows
to discover this without having to create a flic device.
+
+8.14 KVM_CAP_PPC_SAFE_CACHE
+
+Architectures: ppc
+
+This capability gives information about the underlying machine's
+vulnerability or otherwise to the Meltdown attack. Its value is a
+tristate, where 0 indicates the machine is vulnerable, 1 indicates the
+hardware is vulnerable but provides assistance to work around the
+vulnerability (specifically by providing a fast L1 data cache flush
+facility), and 2 indicates that the machine is not vulnerable.
+
+8.15 KVM_CAP_PPC_SAFE_BOUNDS_CHECK
+
+Architectures: ppc
+
+This capability gives information about the underlying machine's
+vulnerability or otherwise to the bounds-check variant of the Spectre
+attack. Its value is a tristate, where 0 indicates the machine is
+vulnerable, 1 indicates the hardware is vulnerable but provides
+assistance to work around the vulnerability (specifically by providing
+an instruction that acts as a speculation barrier), and 2 indicates
+that the machine is not vulnerable.
+
+8.16 KVM_CAP_PPC_SAFE_INDIRECT_BRANCH
+
+Architectures: ppc
+
+This capability gives information about the underlying machine's
+vulnerability or otherwise to the indirect branch variant of the Spectre
+attack. Its value is a tristate, where 0 indicates the machine is
+vulnerable and 2 indicates that the machine is not vulnerable.
+(1 would indicate the availability of a workaround that software
+needs to implement, but there is currently no workaround that needs
+software changes.)
+
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 1915e86..58e863b 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -39,6 +39,10 @@
#include <asm/iommu.h>
#include <asm/switch_to.h>
#include <asm/xive.h>
+#ifdef CONFIG_PPC_PSERIES
+#include <asm/hvcall.h>
+#include <asm/plpar_wrappers.h>
+#endif
#include "timing.h"
#include "irq.h"
@@ -488,6 +492,193 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
module_put(kvm->arch.kvm_ops->owner);
}
+#ifdef CONFIG_PPC_BOOK3S_64
+/*
+ * These functions check whether the underlying hardware is safe
+ * against the Meltdown/Spectre attacks and whether it supplies
+ * instructions for use in workarounds. The information comes from
+ * firmware, either via the device tree on powernv platforms or
+ * from an hcall on pseries platforms.
+ *
+ * For check_safe_cache() and check_safe_bounds_check(), a return
+ * value of 0 means vulnerable, 1 means vulnerable but workaround
+ * instructions are provided, and 2 means not vulnerable (no workaround
+ * is needed).
+ * For check_safe_indirect_branch(), 0 means vulnerable and 2 means
+ * not vulnerable.
+ */
+static inline bool have_fw_feat(struct device_node *fw_features,
+ const char *state, const char *name)
+{
+ struct device_node *np;
+ bool r = false;
+
+ np = of_get_child_by_name(fw_features, name);
+ if (np) {
+ r = of_property_read_bool(np, state);
+ of_node_put(np);
+ }
+ return r;
+}
+
+#ifdef CONFIG_PPC_PSERIES
+static bool check_pseries_safe_cache(int *rp)
+{
+ struct h_cpu_char_result c;
+ unsigned long rc;
+ int r = 0;
+
+ if (!machine_is(pseries))
+ return false;
+
+ rc = plpar_get_cpu_characteristics(&c);
+ if (rc == H_SUCCESS) {
+ if (!(c.behavior & H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV))
+ r = 2;
+ else if ((c.character & H_GET_CPU_CHAR_CHAR_L1D_PRIVATE) &&
+ ((c.character & H_GET_CPU_CHAR_CHAR_ORI30_L1_FLUSH) ||
+ (c.character & H_GET_CPU_CHAR_CHAR_MTTRIG2_L1_FLUSH)))
+ r = 1;
+ }
+ *rp = r;
+ return true;
+}
+
+static bool check_pseries_safe_bounds_check(int *rp)
+{
+ struct h_cpu_char_result c;
+ unsigned long rc;
+ int r = 0;
+
+ if (!machine_is(pseries))
+ return false;
+
+ rc = plpar_get_cpu_characteristics(&c);
+ if (rc == H_SUCCESS) {
+ if (!(c.behavior & H_GET_CPU_CHAR_BEHAV_SPEC_BAR_BNDS_CHK))
+ r = 2;
+ else if (c.character & H_GET_CPU_CHAR_CHAR_ORI31_SPEC_BAR)
+ r = 1;
+ }
+ *rp = r;
+ return true;
+}
+
+static bool check_pseries_safe_indirect_branch(int *rp)
+{
+ struct h_cpu_char_result c;
+ unsigned long rc;
+ int r = 0;
+
+ if (!machine_is(pseries))
+ return false;
+
+ rc = plpar_get_cpu_characteristics(&c);
+ if (rc == H_SUCCESS) {
+ if (c.character & H_GET_CPU_CHAR_CHAR_BCCTR_SERIAL)
+ r = 2;
+ }
+ *rp = r;
+ return true;
+}
+
+#else
+static bool check_pseries_safe_cache(int *rp)
+{
+ return false;
+}
+
+static bool check_pseries_safe_bounds_check(int *rp)
+{
+ return false;
+}
+
+static bool check_pseries_safe_indirect_branch(int *rp)
+{
+ return false;
+}
+#endif
+
+static int check_safe_cache(void)
+{
+ struct device_node *np, *fw_features;
+ int r = 0;
+
+ if (check_pseries_safe_cache(&r))
+ return r;
+
+ np = of_find_node_by_name(NULL, "ibm,opal");
+ if (np) {
+ fw_features = of_get_child_by_name(np, "fw-features");
+ of_node_put(np);
+ if (!fw_features)
+ return 0;
+ if (have_fw_feat(fw_features, "disabled",
+ "needs-l1d-flush-msr-pr-0-to-1"))
+ r = 2;
+ else if (have_fw_feat(fw_features, "enabled",
+ "fw-l1d-thread-split") &&
+ (have_fw_feat(fw_features, "enabled",
+ "inst-l1d-flush-trig2") ||
+ have_fw_feat(fw_features, "enabled",
+ "inst-l1d-flush-ori30,30,0")))
+ r = 1;
+ of_node_put(fw_features);
+ }
+
+ return r;
+}
+
+static int check_safe_bounds_check(void)
+{
+ struct device_node *np, *fw_features;
+ int r = 0;
+
+ if (check_pseries_safe_bounds_check(&r))
+ return r;
+
+ np = of_find_node_by_name(NULL, "ibm,opal");
+ if (np) {
+ fw_features = of_get_child_by_name(np, "fw-features");
+ of_node_put(np);
+ if (!fw_features)
+ return 0;
+ if (have_fw_feat(fw_features, "disabled",
+ "needs-spec-barrier-for-bound-checks"))
+ r = 2;
+ else if (have_fw_feat(fw_features, "enabled",
+ "inst-spec-barrier-ori31,31,0"))
+ r = 1;
+ of_node_put(fw_features);
+ }
+
+ return r;
+}
+
+static int check_safe_indirect_branch(void)
+{
+ struct device_node *np, *fw_features;
+ int r = 0;
+
+ if (check_pseries_safe_indirect_branch(&r))
+ return r;
+
+ np = of_find_node_by_name(NULL, "ibm,opal");
+ if (np) {
+ fw_features = of_get_child_by_name(np, "fw-features");
+ of_node_put(np);
+ if (!fw_features)
+ return 0;
+ if (have_fw_feat(fw_features, "enabled",
+ "fw-bcctrl-serialized"))
+ r = 2;
+ of_node_put(fw_features);
+ }
+
+ return r;
+}
+#endif
+
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
{
int r;
@@ -646,6 +837,17 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = hv_enabled &&
(cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_HTM_COMP);
break;
+#ifdef CONFIG_PPC_BOOK3S_64
+ case KVM_CAP_PPC_SAFE_CACHE:
+ r = check_safe_cache();
+ break;
+ case KVM_CAP_PPC_SAFE_BOUNDS_CHECK:
+ r = check_safe_bounds_check();
+ break;
+ case KVM_CAP_PPC_SAFE_INDIRECT_BRANCH:
+ r = check_safe_indirect_branch();
+ break;
+#endif
default:
r = 0;
break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 496e59a..0a480e9 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -932,6 +932,9 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_HYPERV_SYNIC2 148
#define KVM_CAP_HYPERV_VP_INDEX 149
#define KVM_CAP_S390_AIS_MIGRATION 150
+#define KVM_CAP_PPC_SAFE_CACHE 151
+#define KVM_CAP_PPC_SAFE_BOUNDS_CHECK 152
+#define KVM_CAP_PPC_SAFE_INDIRECT_BRANCH 153
#ifdef KVM_CAP_IRQ_ROUTING
--
2.7.4
^ permalink raw reply related
* Re: [PATCH 0/6] cxlflash: Miscellaneous patches
From: Martin K. Petersen @ 2018-01-09 3:07 UTC (permalink / raw)
To: Uma Krishnan
Cc: linux-scsi, James Bottomley, Martin K. Petersen, Matthew R. Ochs,
Manoj N. Kumar, linuxppc-dev, Andrew Donnellan, Frederic Barrat,
Christophe Lombard
In-Reply-To: <1515020002-43551-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Uma,
> This patch series contains miscellaneous fixes. The first patch fixes
> a bug while the rest improve the code structure and prepare the code
> for future enhancements.
Added stable tag to first patch and applied series to
4.16/scsi-queue. Thank you!
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply
* Re: [PATCH 06/67] hexagon: remove unused flush_write_buffers definition
From: Richard Kuo @ 2018-01-09 3:13 UTC (permalink / raw)
To: Christoph Hellwig
Cc: iommu, linux-alpha, linux-snps-arc, linux-arm-kernel,
adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-7-hch@lst.de>
On Fri, Dec 29, 2017 at 09:18:10AM +0100, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/hexagon/include/asm/io.h | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
> index 66f5e9a61efc..9e8621d94ee9 100644
> --- a/arch/hexagon/include/asm/io.h
> +++ b/arch/hexagon/include/asm/io.h
> @@ -330,8 +330,6 @@ static inline void outsl(unsigned long port, const void *buffer, int count)
> }
> }
>
> -#define flush_write_buffers() do { } while (0)
> -
> #endif /* __KERNEL__ */
>
> #endif
> --
> 2.14.2
>
For Hexagon:
Acked-by: Richard Kuo <rkuo@codeaurora.org>
--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [RFC PATCH kernel] powerpc/mm: Flush "process-scoped translations" when setting MMU type
From: Alexey Kardashevskiy @ 2018-01-09 1:35 UTC (permalink / raw)
To: linuxppc-dev
Cc: Alexey Kardashevskiy, David Gibson, Oliver O'Halloran,
Balbir Singh, Benjamin Herrenschmidt, Michael Ellerman,
Paul Mackerras
This fixes migration on POWER9 machines, especially when migration
starts within first 10 seconds after the guest start.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
This is a reminder that the problem exists, a proper patch and
commit log are still needed. The "(old & PATB_HR)" was tested but
not the other one, something is wrong with hpt guest on radix host.
---
arch/powerpc/mm/pgtable_64.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 813ea22..f690f6d 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -483,10 +483,14 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
if (old & PATB_HR) {
asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+ asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
+ "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
} else {
asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+ asm volatile(PPC_TLBIE_5(%0,%1,2,1,0) : :
+ "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
}
asm volatile("eieio; tlbsync; ptesync" : : : "memory");
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs
From: Michael Ellerman @ 2018-01-08 22:09 UTC (permalink / raw)
To: Thomas Gleixner
Cc: linuxppc-dev, LKML, Peter Zijlstra, npiggin, Anton Blanchard,
mikey, oohall, Paul Mackerras, Greg KH
In-Reply-To: <alpine.DEB.2.20.1801081818060.1735@nanos>
Thomas Gleixner <tglx@linutronix.de> writes:
> On Tue, 9 Jan 2018, Michael Ellerman wrote:
>
> Sorry, I wasn't aware about your efforts and did not cc you. I've just
> queued a more generic sysfs interface for this whole mess:
No worries.
> https://lkml.kernel.org/r/20180107214913.096657732@linutronix.de
>
> It should be simple to extend for write and it would be great if all
> affected architectures could share it.
As you say this has all been a bit of a mess, and as a result we already
have people running kernels with this patch, so we don't want to remove
the 'rfi_flush' file.
But we will certainly add support on powerpc for the files you have
created, in addition to 'rfi_flush'.
cheers
^ permalink raw reply
* Re: [PATCH 03/11] powerpc/64s: Simple RFI macro conversions
From: Michael Ellerman @ 2018-01-08 22:04 UTC (permalink / raw)
To: Paul Mackerras, Peter Zijlstra
Cc: linuxppc-dev, linux-kernel, tglx, npiggin, anton, mikey, oohall
In-Reply-To: <20180108210123.GA9895@fergus.ozlabs.ibm.com>
Paul Mackerras <paulus@ozlabs.org> writes:
> On Mon, Jan 08, 2018 at 06:09:51PM +0100, Peter Zijlstra wrote:
>> On Tue, Jan 09, 2018 at 03:54:45AM +1100, Michael Ellerman wrote:
>> > diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
>> > index 42a4b237df5f..34a5adeff084 100644
>> > --- a/arch/powerpc/kvm/book3s_rmhandlers.S
>> > +++ b/arch/powerpc/kvm/book3s_rmhandlers.S
>> > @@ -46,6 +46,9 @@
>> >
>> > #define FUNC(name) name
>> >
>> > +#define RFI_TO_KERNEL RFI
>> > +#define RFI_TO_GUEST RFI
>> > +
>> > .macro INTERRUPT_TRAMPOLINE intno
>> >
>> > .global kvmppc_trampoline_\intno
>>
>> Leftovers? The previous patch seems to define all that in common
>> headers, why redefine here again?
>
> Not leftovers - this is for the sake of 32-bit compiles. There is
> code in this file and in book3s_segment.S which gets used both for
> 32-bit and 64-bit kernels, and this is supplying a definition on
> 32-bit platforms. Without this, 32-bit builds that have PR KVM
> configured will fail.
Yep.
I was going to put all the RFI macros in a single header, and we could
then have the dummy versions in there as would the usual pattern. But at
this stage it would just complicate life for people doing distro
backports, so I'll do that as a cleanup once it's all merged.
cheers
^ permalink raw reply
* Re: [PATCH 11/11] powerpc/powernv: Check device-tree for RFI flush settings
From: Tyrel Datwyler @ 2018-01-08 21:57 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev
Cc: mikey, peterz, linux-kernel, npiggin, oohall, anton, paulus, tglx
In-Reply-To: <20180108165453.26066-11-mpe@ellerman.id.au>
On 01/08/2018 08:54 AM, Michael Ellerman wrote:
> From: Oliver O'Halloran <oohall@gmail.com>
>
> New device-tree properties are available which tell the hypervisor
> settings related to the RFI flush. Use them to determine the
> appropriate flush instruction to use, and whether the flush is
> required.
>
> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
^ permalink raw reply
* Re: revamp vmem_altmap / dev_pagemap handling V3
From: Michal Hocko @ 2018-01-08 21:50 UTC (permalink / raw)
To: Dan Williams
Cc: Christoph Hellwig, linux-nvdimm, X86 ML,
Linux Kernel Mailing List, Linux MM, Jérôme Glisse,
linuxppc-dev
In-Reply-To: <CAPcyv4ipGv613NgJZ8HEWTV4DrDxRdrMwD=8odZevvBQaQwuCA@mail.gmail.com>
On Mon 08-01-18 13:27:13, Dan Williams wrote:
> On Mon, Jan 8, 2018 at 12:25 PM, Michal Hocko <mhocko@kernel.org> wrote:
> > On Mon 08-01-18 11:44:02, Dan Williams wrote:
> >> On Mon, Jan 8, 2018 at 3:26 AM, Christoph Hellwig <hch@lst.de> wrote:
> >> > Any chance to get this fully reviewed and picked up before the
> >> > end of the merge window?
> >>
> >> I'm fine carrying these through the nvdimm tree, but I'd need an ack
> >> from the mm folks for all the code touches related to arch_add_memory.
> >
> > I am sorry to be slow here but I am out of time right now - yeah having
> > a lot of fun kaiser time. I didn't get to look at these patches at all
> > yet but the changelog suggests that you want to remove vmem_altmap.
> > I've had plans to (ab)use this for self hosted struct pages for memory
> > hotplug http://lkml.kernel.org/r/20170801124111.28881-1-mhocko@kernel.org
> > That work is stalled though because it is buggy and I was too busy to
> > finish that work. Anyway, if you believe that removing vmem_altmap is a
> > good step in general I will find another way. I wasn't really happy how
> > the whole thing is grafted to the memory hotplug and (ab)used it only
> > because it was handy and ready for reuse.
>
> You misread, these are keeping vmem_altmap and cleaning up the usage
> to pass the vmem_altmap pointer through all paths rather than the
> tricky radix lookup we were doing previously.
Good to hear. I really didn't get further than reading through email
subjects and for some reason I misread those.
> > Anyway if you need a review of mm parts from me, you will have to wait
> > some more. If this requires some priority then go ahead and merge
> > it. Times are just too crazy right now.
>
> Since you were planning on reusing vmem_altmap I think these patches
> make your job easier. I don't see the risk in merging these, we've
> squeezed out a few bugs and all the nvdimm unit tests are passing.
Good, then really do not wait for me if this aims to get merged soon.
> > Sorry about that.
>
> No worries, quite a few of us are in that same boat.
Yeah the boat is quite large I suspect...
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: revamp vmem_altmap / dev_pagemap handling V3
From: Dan Williams @ 2018-01-08 21:27 UTC (permalink / raw)
To: Michal Hocko
Cc: Christoph Hellwig, linux-nvdimm, X86 ML,
Linux Kernel Mailing List, Linux MM, Jérôme Glisse,
linuxppc-dev
In-Reply-To: <20180108202548.GA1732@dhcp22.suse.cz>
On Mon, Jan 8, 2018 at 12:25 PM, Michal Hocko <mhocko@kernel.org> wrote:
> On Mon 08-01-18 11:44:02, Dan Williams wrote:
>> On Mon, Jan 8, 2018 at 3:26 AM, Christoph Hellwig <hch@lst.de> wrote:
>> > Any chance to get this fully reviewed and picked up before the
>> > end of the merge window?
>>
>> I'm fine carrying these through the nvdimm tree, but I'd need an ack
>> from the mm folks for all the code touches related to arch_add_memory.
>
> I am sorry to be slow here but I am out of time right now - yeah having
> a lot of fun kaiser time. I didn't get to look at these patches at all
> yet but the changelog suggests that you want to remove vmem_altmap.
> I've had plans to (ab)use this for self hosted struct pages for memory
> hotplug http://lkml.kernel.org/r/20170801124111.28881-1-mhocko@kernel.org
> That work is stalled though because it is buggy and I was too busy to
> finish that work. Anyway, if you believe that removing vmem_altmap is a
> good step in general I will find another way. I wasn't really happy how
> the whole thing is grafted to the memory hotplug and (ab)used it only
> because it was handy and ready for reuse.
You misread, these are keeping vmem_altmap and cleaning up the usage
to pass the vmem_altmap pointer through all paths rather than the
tricky radix lookup we were doing previously.
> Anyway if you need a review of mm parts from me, you will have to wait
> some more. If this requires some priority then go ahead and merge
> it. Times are just too crazy right now.
Since you were planning on reusing vmem_altmap I think these patches
make your job easier. I don't see the risk in merging these, we've
squeezed out a few bugs and all the nvdimm unit tests are passing.
> Sorry about that.
No worries, quite a few of us are in that same boat.
^ permalink raw reply
* Re: [PATCH 03/11] powerpc/64s: Simple RFI macro conversions
From: Paul Mackerras @ 2018-01-08 21:01 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Michael Ellerman, linuxppc-dev, linux-kernel, tglx, npiggin,
anton, mikey, oohall
In-Reply-To: <20180108170951.GB6176@hirez.programming.kicks-ass.net>
On Mon, Jan 08, 2018 at 06:09:51PM +0100, Peter Zijlstra wrote:
> On Tue, Jan 09, 2018 at 03:54:45AM +1100, Michael Ellerman wrote:
> > diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
> > index 42a4b237df5f..34a5adeff084 100644
> > --- a/arch/powerpc/kvm/book3s_rmhandlers.S
> > +++ b/arch/powerpc/kvm/book3s_rmhandlers.S
> > @@ -46,6 +46,9 @@
> >
> > #define FUNC(name) name
> >
> > +#define RFI_TO_KERNEL RFI
> > +#define RFI_TO_GUEST RFI
> > +
> > .macro INTERRUPT_TRAMPOLINE intno
> >
> > .global kvmppc_trampoline_\intno
>
> Leftovers? The previous patch seems to define all that in common
> headers, why redefine here again?
Not leftovers - this is for the sake of 32-bit compiles. There is
code in this file and in book3s_segment.S which gets used both for
32-bit and 64-bit kernels, and this is supplying a definition on
32-bit platforms. Without this, 32-bit builds that have PR KVM
configured will fail.
Paul.
^ permalink raw reply
* [RFC 3/3] postmigration/memory: Associativity & ibm, dynamic-memory-v2
From: Michael Bringmann @ 2018-01-08 20:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Michael Bringmann, Nathan Fontenot
In-Reply-To: <f07a1d2c-46df-f0c3-e1d2-6d605883ce9f@linux.vnet.ibm.com>
postmigration/memory: Now apply changes to the associativity of memory
blocks described by the 'ibm,dynamic-memory-v2' property regarding
the topology of LPARS in Post Migration events.
* Extend the previous work done for the 'ibm,associativity-lookup-array'
to apply to either property 'ibm,dynamic-memory' or
'ibm,dynamic-memory-v2', whichever is present.
* Add new code to parse the 'ibm,dynamic-memory-v2' property looking
for differences in block 'assignment', associativity indexes per
block, and any other difference currently known.
When block differences are recognized, the memory block may be removed,
added, or updated depending upon the state of the new device tree
property and differences from the migrated value of the property.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in RFC:
-- Remove unnecessary spacing changes from patch.
-- Improve patch description.
-- Resubmit as RFC pending further integration with LMB changes
by Nathan Fontenot
---
arch/powerpc/include/asm/prom.h | 12 ++
arch/powerpc/platforms/pseries/hotplug-memory.c | 171 ++++++++++++++++++++++-
2 files changed, 174 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 825bd59..e16ef0f 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -92,6 +92,18 @@ struct of_drconf_cell {
u32 flags;
};
+/* The of_drconf_cell_v2 struct defines the layout of the LMB array
+ * specified in the device tree property
+ * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2
+ */
+struct of_drconf_cell_v2 {
+ u32 num_seq_lmbs;
+ u64 base_address;
+ u32 drc_index;
+ u32 aa_index;
+ u32 flags;
+} __attribute__((packed));
+
#define DRCONF_MEM_ASSIGNED 0x00000008
#define DRCONF_MEM_AI_INVALID 0x00000040
#define DRCONF_MEM_RESERVED 0x00000080
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 04208b0..96eaa9a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1172,14 +1172,112 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
return rc;
}
+static inline int pseries_memory_v2_find_drc(u32 drc_index,
+ u64 *base_addr, unsigned long memblock_size,
+ struct of_drconf_cell_v2 **drmem,
+ struct of_drconf_cell_v2 *last_drmem)
+{
+ struct of_drconf_cell_v2 *dm = (*drmem);
+
+ while (dm < last_drmem) {
+ if ((be32_to_cpu(dm->drc_index) <= drc_index) &&
+ (drc_index <= (be32_to_cpu(dm->drc_index)+
+ be32_to_cpu(dm->num_seq_lmbs)-1))) {
+ int offset = drc_index - be32_to_cpu(dm->drc_index);
+ (*base_addr) = be64_to_cpu(dm->base_address) +
+ (offset * memblock_size);
+ break;
+ } else if (drc_index > (be32_to_cpu(dm->drc_index)+
+ be32_to_cpu(dm->num_seq_lmbs)-1)) {
+ dm++;
+ (*drmem) = dm;
+ } else if (be32_to_cpu(dm->drc_index) > drc_index) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int pseries_update_drconf_memory_v2(struct of_reconfig_data *pr)
+{
+ struct of_drconf_cell_v2 *new_drmem, *old_drmem, *last_old_drmem;
+ unsigned long memblock_size;
+ u32 new_entries, old_entries;
+ u64 old_base_addr;
+ __be32 *p;
+ int i, rc = 0;
+
+ if (rtas_hp_event)
+ return 0;
+
+ memblock_size = pseries_memory_block_size();
+ if (!memblock_size)
+ return -EINVAL;
+
+ /* The first int of the property is the number of lmb's
+ * described by the property. This is followed by an array
+ * of of_drconf_cell_v2 entries. Get the number of entries
+ * and skip to the array of of_drconf_cell_v2's.
+ */
+ p = (__be32 *) pr->old_prop->value;
+ if (!p)
+ return -EINVAL;
+ old_entries = be32_to_cpu(*p++);
+ old_drmem = (struct of_drconf_cell_v2 *)p;
+ last_old_drmem = old_drmem +
+ (sizeof(struct of_drconf_cell_v2) * old_entries);
+
+ p = (__be32 *)pr->prop->value;
+ new_entries = be32_to_cpu(*p++);
+ new_drmem = (struct of_drconf_cell_v2 *)p;
+
+ for (i = 0; i < new_entries; i++) {
+ int j;
+ u32 new_drc_index = be32_to_cpu(new_drmem->drc_index);
+
+ for (j = 0; j < new_drmem->num_seq_lmbs; j++) {
+ if (!pseries_memory_v2_find_drc(new_drc_index+j,
+ &old_base_addr,
+ memblock_size,
+ &old_drmem,
+ last_old_drmem)) {
+ if ((be32_to_cpu(old_drmem->flags) &
+ DRCONF_MEM_ASSIGNED) &&
+ (!(be32_to_cpu(new_drmem->flags) &
+ DRCONF_MEM_ASSIGNED))) {
+ rc = pseries_remove_memblock(
+ old_base_addr,
+ memblock_size);
+ } else if ((!(be32_to_cpu(old_drmem->flags) &
+ DRCONF_MEM_ASSIGNED)) &&
+ (be32_to_cpu(new_drmem->flags) &
+ DRCONF_MEM_ASSIGNED)) {
+ rc = memblock_add(
+ old_base_addr, memblock_size);
+ } else if ((be32_to_cpu(old_drmem->aa_index) !=
+ be32_to_cpu(new_drmem->aa_index)) &&
+ (be32_to_cpu(new_drmem->flags) &
+ DRCONF_MEM_ASSIGNED)) {
+ dlpar_memory_readd_by_index(
+ new_drc_index+j,
+ pr->prop);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
struct assoc_arrays {
u32 n_arrays;
u32 array_sz;
const __be32 *arrays;
};
-static int pseries_update_ala_memory_aai(int aa_index,
- struct property *dmprop)
+static int pseries_update_ala_memory_aai_v1(int aa_index,
+ struct property *dmprop)
{
struct of_drconf_cell *drmem;
u32 entries;
@@ -1211,11 +1309,48 @@ static int pseries_update_ala_memory_aai(int aa_index,
return rc;
}
+static int pseries_update_ala_memory_aai_v2(int aa_index,
+ struct property *dmprop)
+{
+ struct of_drconf_cell_v2 *drmem;
+ u32 entries;
+ __be32 *p;
+ int i;
+
+ p = (__be32 *) dmprop->value;
+ if (!p)
+ return -EINVAL;
+
+ /* The first int of the property is the number of lmb's
+ * described by the property. This is followed by an array
+ * of of_drconf_cell_v2 entries. Get the number of entries
+ * and skip to the array of of_drconf_cell_v2's.
+ */
+ entries = be32_to_cpu(*p++);
+ drmem = (struct of_drconf_cell_v2 *)p;
+
+ for (i = 0; i < entries; i++) {
+ if ((be32_to_cpu(drmem[i].aa_index) != aa_index) &&
+ (be32_to_cpu(drmem[i].flags) & DRCONF_MEM_ASSIGNED)) {
+ int j;
+ int lim = be32_to_cpu(drmem->num_seq_lmbs);
+ u32 drc_index = be32_to_cpu(drmem->drc_index);
+
+ for (j = 0; j < lim; j++)
+ dlpar_memory_readd_by_index(drc_index+j,
+ dmprop);
+ }
+ }
+
+ return 0;
+}
+
static int pseries_update_ala_memory(struct of_reconfig_data *pr)
{
struct assoc_arrays new_ala, old_ala;
struct device_node *dn;
struct property *dmprop;
+ bool v1 = true;
__be32 *p;
int i, lim;
@@ -1228,8 +1363,13 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
dmprop = of_find_property(dn, "ibm,dynamic-memory", NULL);
if (!dmprop) {
- of_node_put(dn);
- return -ENODEV;
+ v1 = false;
+ dmprop = of_find_property(dn, "ibm,dynamic-memory-v2",
+ NULL);
+ if (!dmprop) {
+ of_node_put(dn);
+ return -ENODEV;
+ }
}
/*
@@ -1271,19 +1411,30 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
new_ala.array_sz))
continue;
- pseries_update_ala_memory_aai(i, dmprop);
+ if (v1)
+ pseries_update_ala_memory_aai_v1(i, dmprop);
+ else
+ pseries_update_ala_memory_aai_v2(i, dmprop);
}
- for (i = lim; i < new_ala.n_arrays; i++)
- pseries_update_ala_memory_aai(i, dmprop);
+ for (i = lim; i < new_ala.n_arrays; i++) {
+ if (v1)
+ pseries_update_ala_memory_aai_v1(i, dmprop);
+ else
+ pseries_update_ala_memory_aai_v2(i, dmprop);
+ }
} else {
/* Update all entries representing these rows;
* as all rows have different sizes, none can
* have equivalent values.
*/
- for (i = 0; i < lim; i++)
- pseries_update_ala_memory_aai(i, dmprop);
+ for (i = 0; i < lim; i++) {
+ if (v1)
+ pseries_update_ala_memory_aai_v1(i, dmprop);
+ else
+ pseries_update_ala_memory_aai_v2(i, dmprop);
+ }
}
of_node_put(dn);
@@ -1306,6 +1457,8 @@ static int pseries_memory_notifier(struct notifier_block *nb,
case OF_RECONFIG_UPDATE_PROPERTY:
if (!strcmp(rd->prop->name, "ibm,dynamic-memory"))
err = pseries_update_drconf_memory(rd);
+ if (!strcmp(rd->prop->name, "ibm,dynamic-memory-v2"))
+ err = pseries_update_drconf_memory_v2(rd);
if (!strcmp(rd->prop->name,
"ibm,associativity-lookup-arrays"))
err = pseries_update_ala_memory(rd);
^ permalink raw reply related
* [RFC 2/3] postmigration/memory: Review assoc lookup array changes
From: Michael Bringmann @ 2018-01-08 20:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Michael Bringmann, Nathan Fontenot
In-Reply-To: <f07a1d2c-46df-f0c3-e1d2-6d605883ce9f@linux.vnet.ibm.com>
postmigration/memory: In an LPAR migration scenario, the property
"ibm,associativity-lookup-arrays" may change. In the event that a
row of the array differs, locate all assigned memory blocks with that
'aa_index' and 're-add' them to the system memory block data structures.
In the process of the 're-add', the appropriate entry of the property
'ibm,dynamic-memory' would be updated as well as any other applicable
system data structures.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in RFC:
-- Simplify code to update memory nodes during mobility checks.
Remove functions to generate extra HP_ELOG messages in favor
of direct function calls to dlpar_memory_readd_by_index.
-- Resubmit as RFC pending further integration with LMB changes
by Nathan Fontenot
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 121 +++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 0e2ae20..04208b0 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1172,6 +1172,124 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
return rc;
}
+struct assoc_arrays {
+ u32 n_arrays;
+ u32 array_sz;
+ const __be32 *arrays;
+};
+
+static int pseries_update_ala_memory_aai(int aa_index,
+ struct property *dmprop)
+{
+ struct of_drconf_cell *drmem;
+ u32 entries;
+ __be32 *p;
+ int i;
+ int rc = 0;
+
+ p = (__be32 *) dmprop->value;
+ if (!p)
+ return -EINVAL;
+
+ /* The first int of the property is the number of lmb's
+ * described by the property. This is followed by an array
+ * of of_drconf_cell entries. Get the number of entries
+ * and skip to the array of of_drconf_cell's.
+ */
+ entries = be32_to_cpu(*p++);
+ drmem = (struct of_drconf_cell *)p;
+
+ for (i = 0; i < entries; i++) {
+ if ((be32_to_cpu(drmem[i].aa_index) != aa_index) &&
+ (be32_to_cpu(drmem[i].flags) & DRCONF_MEM_ASSIGNED)) {
+ rc = dlpar_memory_readd_by_index(
+ be32_to_cpu(drmem[i].drc_index),
+ dmprop);
+ }
+ }
+
+ return rc;
+}
+
+static int pseries_update_ala_memory(struct of_reconfig_data *pr)
+{
+ struct assoc_arrays new_ala, old_ala;
+ struct device_node *dn;
+ struct property *dmprop;
+ __be32 *p;
+ int i, lim;
+
+ if (rtas_hp_event)
+ return 0;
+
+ dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (!dn)
+ return -ENODEV;
+
+ dmprop = of_find_property(dn, "ibm,dynamic-memory", NULL);
+ if (!dmprop) {
+ of_node_put(dn);
+ return -ENODEV;
+ }
+
+ /*
+ * The layout of the ibm,associativity-lookup-arrays
+ * property is a number N indicating the number of
+ * associativity arrays, followed by a number M
+ * indicating the size of each associativity array,
+ * followed by a list of N associativity arrays.
+ */
+
+ p = (__be32 *) pr->old_prop->value;
+ if (!p) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+ old_ala.n_arrays = of_read_number(p++, 1);
+ old_ala.array_sz = of_read_number(p++, 1);
+ old_ala.arrays = p;
+
+ p = (__be32 *) pr->prop->value;
+ if (!p) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+ new_ala.n_arrays = of_read_number(p++, 1);
+ new_ala.array_sz = of_read_number(p++, 1);
+ new_ala.arrays = p;
+
+ lim = (new_ala.n_arrays > old_ala.n_arrays) ? old_ala.n_arrays :
+ new_ala.n_arrays;
+
+ if (old_ala.array_sz == new_ala.array_sz) {
+
+ for (i = 0; i < lim; i++) {
+ int index = (i * new_ala.array_sz);
+
+ if (!memcmp(&old_ala.arrays[index],
+ &new_ala.arrays[index],
+ new_ala.array_sz))
+ continue;
+
+ pseries_update_ala_memory_aai(i, dmprop);
+ }
+
+ for (i = lim; i < new_ala.n_arrays; i++)
+ pseries_update_ala_memory_aai(i, dmprop);
+
+ } else {
+ /* Update all entries representing these rows;
+ * as all rows have different sizes, none can
+ * have equivalent values.
+ */
+ for (i = 0; i < lim; i++)
+ pseries_update_ala_memory_aai(i, dmprop);
+ }
+
+ of_node_put(dn);
+ return 0;
+}
+
static int pseries_memory_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -1188,6 +1306,9 @@ static int pseries_memory_notifier(struct notifier_block *nb,
case OF_RECONFIG_UPDATE_PROPERTY:
if (!strcmp(rd->prop->name, "ibm,dynamic-memory"))
err = pseries_update_drconf_memory(rd);
+ if (!strcmp(rd->prop->name,
+ "ibm,associativity-lookup-arrays"))
+ err = pseries_update_ala_memory(rd);
break;
}
return notifier_from_errno(err);
^ permalink raw reply related
* [RFC 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo
From: Michael Bringmann @ 2018-01-08 20:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Michael Bringmann, Nathan Fontenot
In-Reply-To: <f07a1d2c-46df-f0c3-e1d2-6d605883ce9f@linux.vnet.ibm.com>
hotplug/mobility: Recognize more changes to the associativity of
memory blocks described by the 'ibm,dynamic-memory' and 'cpu'
properties when processing the topology of LPARS in Post Migration
events. Previous efforts only recognized whether a memory block's
assignment had changed in the property. Changes here include:
* Checking the aa_index values of the old/new properties and 'readd'
any block for which the setting has changed.
* Checking for changes in cpu associativity and making 'readd' calls
when differences are observed.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in RFC:
-- Simplify code to update CPU nodes during mobility checks.
Remove functions to generate extra HP_ELOG messages in favor
of direct function calls to dlpar_cpu_readd_by_index.
-- Move check for "cpu" node type from pseries_update_cpu to
pseries_smp_notifier in 'hotplug-cpu.c'
-- Remove functions 'pseries_memory_readd_by_index' and
'pseries_cpu_readd_by_index' as no longer needed outside of
'mobility.c'.
-- Update patch for recent checkin compatibility
-- Resubmit as RFC pending further integration with LMB changes
by Nathan Fontenot
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 69 +++++++++++++++++++++++
arch/powerpc/platforms/pseries/hotplug-memory.c | 7 ++
2 files changed, 76 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index a7d14aa7..91ef22a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -636,6 +636,27 @@ static int dlpar_cpu_remove_by_index(u32 drc_index)
return rc;
}
+static int dlpar_cpu_readd_by_index(u32 drc_index)
+{
+ int rc = 0;
+
+ pr_info("Attempting to update CPU, drc index %x\n", drc_index);
+
+ if (dlpar_cpu_remove_by_index(drc_index))
+ rc = -EINVAL;
+ else if (dlpar_cpu_add(drc_index))
+ rc = -EINVAL;
+
+ if (rc)
+ pr_info("Failed to update cpu at drc_index %lx\n",
+ (unsigned long int)drc_index);
+ else
+ pr_info("CPU at drc_index %lx was updated\n",
+ (unsigned long int)drc_index);
+
+ return rc;
+}
+
static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
{
struct device_node *dn;
@@ -826,6 +847,9 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
else
rc = -EINVAL;
break;
+ case PSERIES_HP_ELOG_ACTION_READD:
+ rc = dlpar_cpu_readd_by_index(drc_index);
+ break;
default:
pr_err("Invalid action (%d) specified\n", hp_elog->action);
rc = -EINVAL;
@@ -876,12 +900,53 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+static int pseries_update_cpu(struct of_reconfig_data *pr)
+{
+ u32 old_entries, new_entries;
+ __be32 *p, *old_assoc, *new_assoc;
+ int rc = 0;
+
+ /* So far, we only handle the 'ibm,associativity' property,
+ * here.
+ * The first int of the property is the number of domains
+ * described. This is followed by an array of level values.
+ */
+ p = (__be32 *) pr->old_prop->value;
+ if (!p)
+ return -EINVAL;
+ old_entries = be32_to_cpu(*p++);
+ old_assoc = p;
+
+ p = (__be32 *)pr->prop->value;
+ if (!p)
+ return -EINVAL;
+ new_entries = be32_to_cpu(*p++);
+ new_assoc = p;
+
+ if (old_entries == new_entries) {
+ int sz = old_entries * sizeof(int);
+
+ if (!memcmp(old_assoc, new_assoc, sz))
+ rc = dlpar_cpu_readd_by_index(
+ be32_to_cpu(pr->dn->phandle));
+
+ } else {
+ rc = dlpar_cpu_readd_by_index(
+ be32_to_cpu(pr->dn->phandle));
+ }
+
+ return rc;
+}
+
static int pseries_smp_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct of_reconfig_data *rd = data;
int err = 0;
+ if (strcmp(rd->dn->type, "cpu"))
+ return notifier_from_errno(err);
+
switch (action) {
case OF_RECONFIG_ATTACH_NODE:
err = pseries_add_processor(rd->dn);
@@ -889,6 +954,10 @@ static int pseries_smp_notifier(struct notifier_block *nb,
case OF_RECONFIG_DETACH_NODE:
pseries_remove_processor(rd->dn);
break;
+ case OF_RECONFIG_UPDATE_PROPERTY:
+ if (!strcmp(rd->prop->name, "ibm,associativity"))
+ err = pseries_update_cpu(rd);
+ break;
}
return notifier_from_errno(err);
}
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 1d48ab4..0e2ae20 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1160,6 +1160,13 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
memblock_size);
rc = (rc < 0) ? -EINVAL : 0;
break;
+ } else if ((be32_to_cpu(old_drmem[i].aa_index) !=
+ be32_to_cpu(new_drmem[i].aa_index)) &&
+ (be32_to_cpu(new_drmem[i].flags) &
+ DRCONF_MEM_ASSIGNED)) {
+ rc = dlpar_memory_readd_by_index(
+ be32_to_cpu(new_drmem[i].drc_index),
+ pr->prop);
}
}
return rc;
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox