* Re: [PATCH 1/2] mm/mprotect: Call arch_validate_prot under mmap_lock and with length
From: Khalid Aziz @ 2020-10-12 19:14 UTC (permalink / raw)
To: Catalin Marinas
Cc: Jann Horn, linuxppc-dev, linux-kernel, Christoph Hellwig,
linux-mm, Paul Mackerras, sparclinux, Anthony Yznaga,
Andrew Morton, Will Deacon, David S. Miller, linux-arm-kernel
In-Reply-To: <20201012172218.GE6493@gaia>
On 10/12/20 11:22 AM, Catalin Marinas wrote:
> On Mon, Oct 12, 2020 at 11:03:33AM -0600, Khalid Aziz wrote:
>> On 10/10/20 5:09 AM, Catalin Marinas wrote:
>>> On Wed, Oct 07, 2020 at 02:14:09PM -0600, Khalid Aziz wrote:
>>>> On 10/7/20 1:39 AM, Jann Horn wrote:
>>>>> arch_validate_prot() is a hook that can validate whether a given set of
>>>>> protection flags is valid in an mprotect() operation. It is given the set
>>>>> of protection flags and the address being modified.
>>>>>
>>>>> However, the address being modified can currently not actually be used in
>>>>> a meaningful way because:
>>>>>
>>>>> 1. Only the address is given, but not the length, and the operation can
>>>>> span multiple VMAs. Therefore, the callee can't actually tell which
>>>>> virtual address range, or which VMAs, are being targeted.
>>>>> 2. The mmap_lock is not held, meaning that if the callee were to check
>>>>> the VMA at @addr, that VMA would be unrelated to the one the
>>>>> operation is performed on.
>>>>>
>>>>> Currently, custom arch_validate_prot() handlers are defined by
>>>>> arm64, powerpc and sparc.
>>>>> arm64 and powerpc don't care about the address range, they just check the
>>>>> flags against CPU support masks.
>>>>> sparc's arch_validate_prot() attempts to look at the VMA, but doesn't take
>>>>> the mmap_lock.
>>>>>
>>>>> Change the function signature to also take a length, and move the
>>>>> arch_validate_prot() call in mm/mprotect.c down into the locked region.
>>> [...]
>>>> As Chris pointed out, the call to arch_validate_prot() from do_mmap2()
>>>> is made without holding mmap_lock. Lock is not acquired until
>>>> vm_mmap_pgoff(). This variance is uncomfortable but I am more
>>>> uncomfortable forcing all implementations of validate_prot to require
>>>> mmap_lock be held when non-sparc implementations do not have such need
>>>> yet. Since do_mmap2() is in powerpc specific code, for now this patch
>>>> solves a current problem.
>>>
>>> I still think sparc should avoid walking the vmas in
>>> arch_validate_prot(). The core code already has the vmas, though not
>>> when calling arch_validate_prot(). That's one of the reasons I added
>>> arch_validate_flags() with the MTE patches. For sparc, this could be
>>> (untested, just copied the arch_validate_prot() code):
>>
>> I am little uncomfortable with the idea of validating protection bits
>> inside the VMA walk loop in do_mprotect_pkey(). When ADI is being
>> enabled across multiple VMAs and arch_validate_flags() fails on a VMA
>> later, do_mprotect_pkey() will bail out with error leaving ADI enabled
>> on earlier VMAs. This will apply to protection bits other than ADI as
>> well of course. This becomes a partial failure of mprotect() call. I
>> think it should be all or nothing with mprotect() - when one calls
>> mprotect() from userspace, either the entire address range passed in
>> gets its protection bits updated or none of it does. That requires
>> validating protection bits upfront or undoing what earlier iterations of
>> VMA walk loop might have done.
>
> I thought the same initially but mprotect() already does this with the
> VM_MAY* flag checking. If you ask it for an mprotect() that crosses
> multiple vmas and one of them fails, it doesn't roll back the changes to
> the prior ones. I considered that a similar approach is fine for MTE
> (it's most likely a user error).
>
You are right about the current behavior with VM_MAY* flags, but that is
not the right behavior. Adding more cases to this just perpetuates
incorrect behavior. It is not easy to roll back changes after VMAs have
potentially been split/merged which is probably why the current code
simply throws in the towel and returns with partially modified address
space. It is lot easier to do all the checks upfront and then proceed or
not proceed with modifying VMAs. One approach might be to call
arch_validate_flags() in a loop before modifying VMAs and walk all VMAs
with a read lock held. Current code also bails out with ENOMEM if it
finds a hole in the address range and leaves any modifications already
made in place. This is another case where a hole could have been
detected earlier.
--
Khalid
^ permalink raw reply
* Re: [PATCH] ASoC: fsl_spdif: Add support for higher sample rates
From: Nicolin Chen @ 2020-10-12 19:00 UTC (permalink / raw)
To: Shengjiu Wang
Cc: alsa-devel, timur, Xiubo.Lee, linuxppc-dev, tiwai, perex, broonie,
festevam, linux-kernel
In-Reply-To: <1602492582-3558-1-git-send-email-shengjiu.wang@nxp.com>
Hi Shengjiu,
On Mon, Oct 12, 2020 at 04:49:42PM +0800, Shengjiu Wang wrote:
> Add 88200Hz and 176400Hz sample rates support for TX.
> Add 88200Hz, 176400Hz, 192000Hz sample rates support for RX.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Probably should put your own Signed-off at the bottom?
Anyway:
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
^ permalink raw reply
* Re: [PATCH 1/2] mm/mprotect: Call arch_validate_prot under mmap_lock and with length
From: Catalin Marinas @ 2020-10-12 17:22 UTC (permalink / raw)
To: Khalid Aziz
Cc: Jann Horn, linuxppc-dev, linux-kernel, Christoph Hellwig,
linux-mm, Paul Mackerras, sparclinux, Anthony Yznaga,
Andrew Morton, Will Deacon, David S. Miller, linux-arm-kernel
In-Reply-To: <af207cf8-3049-85eb-349d-5fed6b9be49c@oracle.com>
On Mon, Oct 12, 2020 at 11:03:33AM -0600, Khalid Aziz wrote:
> On 10/10/20 5:09 AM, Catalin Marinas wrote:
> > On Wed, Oct 07, 2020 at 02:14:09PM -0600, Khalid Aziz wrote:
> >> On 10/7/20 1:39 AM, Jann Horn wrote:
> >>> arch_validate_prot() is a hook that can validate whether a given set of
> >>> protection flags is valid in an mprotect() operation. It is given the set
> >>> of protection flags and the address being modified.
> >>>
> >>> However, the address being modified can currently not actually be used in
> >>> a meaningful way because:
> >>>
> >>> 1. Only the address is given, but not the length, and the operation can
> >>> span multiple VMAs. Therefore, the callee can't actually tell which
> >>> virtual address range, or which VMAs, are being targeted.
> >>> 2. The mmap_lock is not held, meaning that if the callee were to check
> >>> the VMA at @addr, that VMA would be unrelated to the one the
> >>> operation is performed on.
> >>>
> >>> Currently, custom arch_validate_prot() handlers are defined by
> >>> arm64, powerpc and sparc.
> >>> arm64 and powerpc don't care about the address range, they just check the
> >>> flags against CPU support masks.
> >>> sparc's arch_validate_prot() attempts to look at the VMA, but doesn't take
> >>> the mmap_lock.
> >>>
> >>> Change the function signature to also take a length, and move the
> >>> arch_validate_prot() call in mm/mprotect.c down into the locked region.
> > [...]
> >> As Chris pointed out, the call to arch_validate_prot() from do_mmap2()
> >> is made without holding mmap_lock. Lock is not acquired until
> >> vm_mmap_pgoff(). This variance is uncomfortable but I am more
> >> uncomfortable forcing all implementations of validate_prot to require
> >> mmap_lock be held when non-sparc implementations do not have such need
> >> yet. Since do_mmap2() is in powerpc specific code, for now this patch
> >> solves a current problem.
> >
> > I still think sparc should avoid walking the vmas in
> > arch_validate_prot(). The core code already has the vmas, though not
> > when calling arch_validate_prot(). That's one of the reasons I added
> > arch_validate_flags() with the MTE patches. For sparc, this could be
> > (untested, just copied the arch_validate_prot() code):
>
> I am little uncomfortable with the idea of validating protection bits
> inside the VMA walk loop in do_mprotect_pkey(). When ADI is being
> enabled across multiple VMAs and arch_validate_flags() fails on a VMA
> later, do_mprotect_pkey() will bail out with error leaving ADI enabled
> on earlier VMAs. This will apply to protection bits other than ADI as
> well of course. This becomes a partial failure of mprotect() call. I
> think it should be all or nothing with mprotect() - when one calls
> mprotect() from userspace, either the entire address range passed in
> gets its protection bits updated or none of it does. That requires
> validating protection bits upfront or undoing what earlier iterations of
> VMA walk loop might have done.
I thought the same initially but mprotect() already does this with the
VM_MAY* flag checking. If you ask it for an mprotect() that crosses
multiple vmas and one of them fails, it doesn't roll back the changes to
the prior ones. I considered that a similar approach is fine for MTE
(it's most likely a user error).
--
Catalin
^ permalink raw reply
* Re: [PATCH 1/2] mm/mprotect: Call arch_validate_prot under mmap_lock and with length
From: Khalid Aziz @ 2020-10-12 17:03 UTC (permalink / raw)
To: Catalin Marinas
Cc: Jann Horn, linuxppc-dev, linux-kernel, Christoph Hellwig,
linux-mm, Paul Mackerras, sparclinux, Anthony Yznaga,
Andrew Morton, Will Deacon, David S. Miller, linux-arm-kernel
In-Reply-To: <20201010110949.GA32545@gaia>
On 10/10/20 5:09 AM, Catalin Marinas wrote:
> Hi Khalid,
>
> On Wed, Oct 07, 2020 at 02:14:09PM -0600, Khalid Aziz wrote:
>> On 10/7/20 1:39 AM, Jann Horn wrote:
>>> arch_validate_prot() is a hook that can validate whether a given set of
>>> protection flags is valid in an mprotect() operation. It is given the set
>>> of protection flags and the address being modified.
>>>
>>> However, the address being modified can currently not actually be used in
>>> a meaningful way because:
>>>
>>> 1. Only the address is given, but not the length, and the operation can
>>> span multiple VMAs. Therefore, the callee can't actually tell which
>>> virtual address range, or which VMAs, are being targeted.
>>> 2. The mmap_lock is not held, meaning that if the callee were to check
>>> the VMA at @addr, that VMA would be unrelated to the one the
>>> operation is performed on.
>>>
>>> Currently, custom arch_validate_prot() handlers are defined by
>>> arm64, powerpc and sparc.
>>> arm64 and powerpc don't care about the address range, they just check the
>>> flags against CPU support masks.
>>> sparc's arch_validate_prot() attempts to look at the VMA, but doesn't take
>>> the mmap_lock.
>>>
>>> Change the function signature to also take a length, and move the
>>> arch_validate_prot() call in mm/mprotect.c down into the locked region.
> [...]
>> As Chris pointed out, the call to arch_validate_prot() from do_mmap2()
>> is made without holding mmap_lock. Lock is not acquired until
>> vm_mmap_pgoff(). This variance is uncomfortable but I am more
>> uncomfortable forcing all implementations of validate_prot to require
>> mmap_lock be held when non-sparc implementations do not have such need
>> yet. Since do_mmap2() is in powerpc specific code, for now this patch
>> solves a current problem.
>
> I still think sparc should avoid walking the vmas in
> arch_validate_prot(). The core code already has the vmas, though not
> when calling arch_validate_prot(). That's one of the reasons I added
> arch_validate_flags() with the MTE patches. For sparc, this could be
> (untested, just copied the arch_validate_prot() code):
I am little uncomfortable with the idea of validating protection bits
inside the VMA walk loop in do_mprotect_pkey(). When ADI is being
enabled across multiple VMAs and arch_validate_flags() fails on a VMA
later, do_mprotect_pkey() will bail out with error leaving ADI enabled
on earlier VMAs. This will apply to protection bits other than ADI as
well of course. This becomes a partial failure of mprotect() call. I
think it should be all or nothing with mprotect() - when one calls
mprotect() from userspace, either the entire address range passed in
gets its protection bits updated or none of it does. That requires
validating protection bits upfront or undoing what earlier iterations of
VMA walk loop might have done.
--
Khalid
>
> static inline bool arch_validate_flags(unsigned long vm_flags)
> {
> if (!(vm_flags & VM_SPARC_ADI))
> return true;
>
> if (!adi_capable())
> return false;
>
> /* ADI can not be enabled on PFN mapped pages */
> if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
> return false;
>
> /*
> * Mergeable pages can become unmergeable if ADI is enabled on
> * them even if they have identical data on them. This can be
> * because ADI enabled pages with identical data may still not
> * have identical ADI tags on them. Disallow ADI on mergeable
> * pages.
> */
> if (vma->vm_flags & VM_MERGEABLE)
> return false;
>
> return true;
> }
>
>> That leaves open the question of should
>> generic mmap call arch_validate_prot and return EINVAL for invalid
>> combination of protection bits, but that is better addressed in a
>> separate patch.
>
> The above would cover mmap() as well.
>
> The current sparc_validate_prot() relies on finding the vma for the
> corresponding address. However, if you call this early in the mmap()
> path, there's no such vma. It is only created later in mmap_region()
> which no longer has the original PROT_* flags (all converted to VM_*
> flags).
>
> Calling arch_validate_flags() on mmap() has a small side-effect on the
> user ABI: if the CPU is not adi_capable(), PROT_ADI is currently ignored
> on mmap() but rejected by sparc_validate_prot(). Powerpc already does
> this already and I think it should be fine for arm64 (it needs checking
> though as we have another flag, PROT_BTI, hopefully dynamic loaders
> don't pass this flag unconditionally).
>
> However, as I said above, it doesn't solve the mmap() PROT_ADI checking
> for sparc since there's no vma yet. I'd strongly recommend the
> arch_validate_flags() approach and reverting the "start" parameter added
> to arch_validate_prot() if you go for the flags route.
>
> Thanks.
>
^ permalink raw reply
* Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
From: Matthew Wilcox @ 2020-10-12 16:44 UTC (permalink / raw)
To: Dave Hansen
Cc: linux-aio, linux-efi, kvm, linux-doc, Peter Zijlstra, linux-mmc,
Dave Hansen, dri-devel, linux-mm, target-devel, linux-mtd,
linux-kselftest, linux-f2fs-devel, Ira Weiny, Thomas Gleixner,
drbd-dev, devel, linux-cifs, linux-nilfs, linux-scsi,
linux-nvdimm, linux-rdma, x86, amd-gfx, linux-afs, Eric Biggers,
Ingo Molnar, intel-wired-lan, kexec, xen-devel, linux-ext4, bpf,
Dan Williams, Fenghua Yu, intel-gfx, ecryptfs, linux-um,
reiserfs-devel, linux-block, linux-bcache, Borislav Petkov,
Andy Lutomirski, Jaegeuk Kim, ceph-devel, io-uring, linux-cachefs,
linux-nfs, linux-ntfs-dev, netdev, linuxppc-dev, samba-technical,
linux-kernel, cluster-devel, linux-fsdevel, Andrew Morton,
linux-erofs, linux-btrfs
In-Reply-To: <5d621db9-23d4-e140-45eb-d7fca2093d2b@intel.com>
On Mon, Oct 12, 2020 at 09:28:29AM -0700, Dave Hansen wrote:
> kmap_atomic() is always preferred over kmap()/kmap_thread().
> kmap_atomic() is _much_ more lightweight since its TLB invalidation is
> always CPU-local and never broadcast.
>
> So, basically, unless you *must* sleep while the mapping is in place,
> kmap_atomic() is preferred.
But kmap_atomic() disables preemption, so the _ideal_ interface would map
it only locally, then on preemption make it global. I don't even know
if that _can_ be done. But this email makes it seem like kmap_atomic()
has no downsides.
^ permalink raw reply
* Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
From: Dave Hansen @ 2020-10-12 16:28 UTC (permalink / raw)
To: Eric Biggers, Ira Weiny
Cc: linux-aio, linux-efi, kvm, linux-doc, Peter Zijlstra, linux-mmc,
Dave Hansen, dri-devel, linux-mm, target-devel, linux-mtd,
amd-gfx, linux-kselftest, Thomas Gleixner, drbd-dev, devel,
linux-cifs, linux-nilfs, linux-scsi, linux-nvdimm, linux-rdma,
x86, Matthew Wilcox, linux-afs, cluster-devel, Ingo Molnar,
intel-wired-lan, kexec, xen-devel, linux-ext4, bpf, Dan Williams,
Fenghua Yu, intel-gfx, ecryptfs, linux-um, reiserfs-devel,
linux-block, linux-bcache, Borislav Petkov, Andy Lutomirski,
Jaegeuk Kim, ceph-devel, io-uring, linux-cachefs, linux-nfs,
linux-ntfs-dev, netdev, linuxppc-dev, samba-technical,
linux-kernel, linux-f2fs-devel, linux-fsdevel, Andrew Morton,
linux-erofs, linux-btrfs
In-Reply-To: <20201012161946.GA858@sol.localdomain>
On 10/12/20 9:19 AM, Eric Biggers wrote:
> On Sun, Oct 11, 2020 at 11:56:35PM -0700, Ira Weiny wrote:
>>> And I still don't really understand. After this patchset, there is still code
>>> nearly identical to the above (doing a temporary mapping just for a memcpy) that
>>> would still be using kmap_atomic().
>> I don't understand. You mean there would be other call sites calling:
>>
>> kmap_atomic()
>> memcpy()
>> kunmap_atomic()
> Yes, there are tons of places that do this. Try 'git grep -A6 kmap_atomic'
> and look for memcpy().
>
> Hence why I'm asking what will be the "recommended" way to do this...
> kunmap_thread() or kmap_atomic()?
kmap_atomic() is always preferred over kmap()/kmap_thread().
kmap_atomic() is _much_ more lightweight since its TLB invalidation is
always CPU-local and never broadcast.
So, basically, unless you *must* sleep while the mapping is in place,
kmap_atomic() is preferred.
^ permalink raw reply
* Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
From: Eric Biggers @ 2020-10-12 16:19 UTC (permalink / raw)
To: Ira Weiny
Cc: linux-aio, linux-efi, kvm, linux-doc, Peter Zijlstra, linux-mmc,
Dave Hansen, dri-devel, linux-mm, target-devel, linux-mtd,
amd-gfx, linux-kselftest, Thomas Gleixner, drbd-dev, devel,
linux-cifs, linux-nilfs, linux-scsi, linux-nvdimm, linux-rdma,
x86, Matthew Wilcox, linux-afs, cluster-devel, Ingo Molnar,
intel-wired-lan, kexec, xen-devel, linux-ext4, bpf, Dan Williams,
Fenghua Yu, intel-gfx, ecryptfs, linux-um, reiserfs-devel,
linux-block, linux-bcache, Borislav Petkov, Andy Lutomirski,
Jaegeuk Kim, ceph-devel, io-uring, linux-cachefs, linux-nfs,
linux-ntfs-dev, netdev, linuxppc-dev, samba-technical,
linux-kernel, linux-f2fs-devel, linux-fsdevel, Andrew Morton,
linux-erofs, linux-btrfs
In-Reply-To: <20201012065635.GB2046448@iweiny-DESK2.sc.intel.com>
On Sun, Oct 11, 2020 at 11:56:35PM -0700, Ira Weiny wrote:
> >
> > And I still don't really understand. After this patchset, there is still code
> > nearly identical to the above (doing a temporary mapping just for a memcpy) that
> > would still be using kmap_atomic().
>
> I don't understand. You mean there would be other call sites calling:
>
> kmap_atomic()
> memcpy()
> kunmap_atomic()
Yes, there are tons of places that do this. Try 'git grep -A6 kmap_atomic'
and look for memcpy().
Hence why I'm asking what will be the "recommended" way to do this...
kunmap_thread() or kmap_atomic()?
> And since I don't know the call site details if there are kmap_thread() calls
> which are better off as kmap_atomic() calls I think it is worth converting
> them. But I made the assumption that kmap users would already be calling
> kmap_atomic() if they could (because it is more efficient).
Not necessarily. In cases where either one is correct, people might not have
put much thought into which of kmap() and kmap_atomic() they are using.
- Eric
^ permalink raw reply
* Re: [RFC v1 2/2] KVM: PPC: Book3S HV: abstract secure VM related calls.
From: Ram Pai @ 2020-10-12 16:13 UTC (permalink / raw)
To: Bharata B Rao; +Cc: linuxppc-dev, kvm-ppc, farosas
In-Reply-To: <20201012152836.GK185637@in.ibm.com>
On Mon, Oct 12, 2020 at 08:58:36PM +0530, Bharata B Rao wrote:
> On Mon, Oct 12, 2020 at 12:27:43AM -0700, Ram Pai wrote:
> > Abstract the secure VM related calls into generic calls.
> >
> > These generic calls will call the corresponding method of the
> > backend that prvoides the implementation to support secure VM.
> >
> > Currently there is only the ultravisor based implementation.
> > Modify that implementation to act as a backed to the generic calls.
> >
> > This plumbing will provide the flexibility to add more backends
> > in the future.
> >
> > Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> > ---
> > arch/powerpc/include/asm/kvm_book3s_uvmem.h | 100 -----------
> > arch/powerpc/include/asm/kvmppc_svm_backend.h | 250 ++++++++++++++++++++++++++
> > arch/powerpc/kvm/book3s_64_mmu_radix.c | 6 +-
> > arch/powerpc/kvm/book3s_hv.c | 28 +--
> > arch/powerpc/kvm/book3s_hv_uvmem.c | 78 ++++++--
> > 5 files changed, 327 insertions(+), 135 deletions(-)
> > delete mode 100644 arch/powerpc/include/asm/kvm_book3s_uvmem.h
> > create mode 100644 arch/powerpc/include/asm/kvmppc_svm_backend.h
> >
> > diff --git a/arch/powerpc/include/asm/kvmppc_svm_backend.h b/arch/powerpc/include/asm/kvmppc_svm_backend.h
> > new file mode 100644
> > index 0000000..be60d80
> > --- /dev/null
> > +++ b/arch/powerpc/include/asm/kvmppc_svm_backend.h
> > @@ -0,0 +1,250 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + *
> > + * Copyright IBM Corp. 2020
> > + *
> > + * Authors: Ram Pai <linuxram@us.ibm.com>
> > + */
> > +
> > +#ifndef __POWERPC_KVMPPC_SVM_BACKEND_H__
> > +#define __POWERPC_KVMPPC_SVM_BACKEND_H__
> > +
> > +#include <linux/mutex.h>
> > +#include <linux/timer.h>
> > +#include <linux/types.h>
> > +#include <linux/kvm_types.h>
> > +#include <linux/kvm_host.h>
> > +#include <linux/bug.h>
> > +#ifdef CONFIG_PPC_BOOK3S
> > +#include <asm/kvm_book3s.h>
> > +#else
> > +#include <asm/kvm_booke.h>
> > +#endif
> > +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
> > +#include <asm/paca.h>
> > +#include <asm/xive.h>
> > +#include <asm/cpu_has_feature.h>
> > +#endif
> > +
> > +struct kvmppc_hmm_backend {
>
> Though we started with HMM initially, what we ended up with eventually
> has nothing to do with HMM. Please don't introduce hmm again :-)
Hmm.. its still a extension to HMM to help manage device memory.
right? What am i missing?
>
> > + /* initialize */
> > + int (*kvmppc_secmem_init)(void);
> > +
> > + /* cleanup */
> > + void (*kvmppc_secmem_free)(void);
> > +
> > + /* is memory available */
> > + bool (*kvmppc_secmem_available)(void);
> > +
> > + /* allocate a protected/secure page for the secure VM */
> > + unsigned long (*kvmppc_svm_page_in)(struct kvm *kvm,
> > + unsigned long gra,
> > + unsigned long flags,
> > + unsigned long page_shift);
> > +
> > + /* recover the protected/secure page from the secure VM */
> > + unsigned long (*kvmppc_svm_page_out)(struct kvm *kvm,
> > + unsigned long gra,
> > + unsigned long flags,
> > + unsigned long page_shift);
> > +
> > + /* initiate the transition of a VM to secure VM */
> > + unsigned long (*kvmppc_svm_init_start)(struct kvm *kvm);
> > +
> > + /* finalize the transition of a secure VM */
> > + unsigned long (*kvmppc_svm_init_done)(struct kvm *kvm);
> > +
> > + /* share the page on page fault */
> > + int (*kvmppc_svm_page_share)(struct kvm *kvm, unsigned long gfn);
> > +
> > + /* abort the transition to a secure VM */
> > + unsigned long (*kvmppc_svm_init_abort)(struct kvm *kvm);
> > +
> > + /* add a memory slot */
> > + int (*kvmppc_svm_memslot_create)(struct kvm *kvm,
> > + const struct kvm_memory_slot *new);
> > +
> > + /* free a memory slot */
> > + void (*kvmppc_svm_memslot_delete)(struct kvm *kvm,
> > + const struct kvm_memory_slot *old);
> > +
> > + /* drop pages allocated to the secure VM */
> > + void (*kvmppc_svm_drop_pages)(const struct kvm_memory_slot *free,
> > + struct kvm *kvm, bool skip_page_out);
> > +};
>
> Since the structure has kvmppc_ prefix, may be you can drop
> the same from its members to make the fields smaller?
ok.
>
> > +
> > +extern const struct kvmppc_hmm_backend *kvmppc_svm_backend;
> > +
> > +static inline int kvmppc_svm_page_share(struct kvm *kvm, unsigned long gfn)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return -ENODEV;
> > +
> > + return kvmppc_svm_backend->kvmppc_svm_page_share(kvm,
> > + gfn);
> > +}
> > +
> > +static inline void kvmppc_svm_drop_pages(const struct kvm_memory_slot *memslot,
> > + struct kvm *kvm, bool skip_page_out)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return;
> > +
> > + kvmppc_svm_backend->kvmppc_svm_drop_pages(memslot,
> > + kvm, skip_page_out);
> > +}
> > +
> > +static inline int kvmppc_svm_page_in(struct kvm *kvm,
> > + unsigned long gpa,
> > + unsigned long flags,
> > + unsigned long page_shift)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return -ENODEV;
> > +
> > + return kvmppc_svm_backend->kvmppc_svm_page_in(kvm,
> > + gpa, flags, page_shift);
> > +}
> > +
> > +static inline int kvmppc_svm_page_out(struct kvm *kvm,
> > + unsigned long gpa,
> > + unsigned long flags,
> > + unsigned long page_shift)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return -ENODEV;
> > +
> > + return kvmppc_svm_backend->kvmppc_svm_page_out(kvm,
> > + gpa, flags, page_shift);
> > +}
> > +
> > +static inline int kvmppc_svm_init_start(struct kvm *kvm)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return -ENODEV;
> > +
> > + return kvmppc_svm_backend->kvmppc_svm_init_start(kvm);
> > +}
> > +
> > +static inline int kvmppc_svm_init_done(struct kvm *kvm)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return -ENODEV;
> > +
> > + return kvmppc_svm_backend->kvmppc_svm_init_done(kvm);
> > +}
> > +
> > +static inline int kvmppc_svm_init_abort(struct kvm *kvm)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return -ENODEV;
> > +
> > + return kvmppc_svm_backend->kvmppc_svm_init_abort(kvm);
> > +}
> > +
> > +static inline void kvmppc_svm_memslot_create(struct kvm *kvm,
> > + const struct kvm_memory_slot *memslot)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return;
> > +
> > + kvmppc_svm_backend->kvmppc_svm_memslot_create(kvm,
> > + memslot);
> > +}
> > +
> > +static inline void kvmppc_svm_memslot_delete(struct kvm *kvm,
> > + const struct kvm_memory_slot *memslot)
> > +{
> > + if (!kvmppc_svm_backend)
> > + return;
> > +
> > + kvmppc_svm_backend->kvmppc_svm_memslot_delete(kvm,
> > + memslot);
> > +}
> > +
> > +static inline int kvmppc_secmem_init(void)
> > +{
> > +#ifdef CONFIG_PPC_UV
> > + extern const struct kvmppc_hmm_backend kvmppc_uvmem_backend;
> > +
> > + kvmppc_svm_backend = NULL;
> > + if (kvmhv_on_pseries()) {
> > + /* @TODO add the protected memory backend */
> > + return 0;
> > + }
> > +
> > + kvmppc_svm_backend = &kvmppc_uvmem_backend;
> > +
> > + if (!kvmppc_svm_backend->kvmppc_secmem_init) {
>
> You have a function named kvmppc_secmem_init() and the field
> named the same, can be confusing.
ok. anyway the 'kvmppc' of the field will go away as per your comment
above. So the confusion will also go away :)
>
> > + pr_err("KVM-HV: kvmppc_svm_backend has no %s\n", __func__);
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_secmem_free) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_secmem_free()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_secmem_available) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_secmem_available()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_page_in) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_page_in()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_page_out) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_page_out()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_init_start) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_init_start()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_init_done) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_init_done()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_page_share) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_page_share()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_init_abort) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_init_abort()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_memslot_create) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_memslot_create()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_memslot_delete) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_memslot_delete()\n");
> > + goto err;
> > + }
> > + if (!kvmppc_svm_backend->kvmppc_svm_drop_pages) {
> > + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_drop_pages()\n");
> > + goto err;
> > + }
>
> Do you really need to check each and every callback like above?
> If so, may be the check can be optimized?
It gets checked only the first time, when the backend is introduced.
If we dont check it during initialization, then we will have to check
everytime the method is called. So it is optimized in that sense.
Do you see a better way to optimize it?
Thanks for your comments,
RP
^ permalink raw reply
* [PATCH v2] powerpc/mm: Add mask of always present MMU features
From: Christophe Leroy @ 2020-10-12 15:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
On the same principle as commit 773edeadf672 ("powerpc/mm: Add mask
of possible MMU features"), add mask for MMU features that are
always there in order to optimise out dead branches.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
v2: Features must be anded with MMU_FTRS_POSSIBLE instead of ~0, otherwise
MMU_FTRS_ALWAYS is ~0 when no #ifdef matches.
---
arch/powerpc/include/asm/mmu.h | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 255a1837e9f7..64e7e7f7cda9 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -201,8 +201,30 @@ enum {
0,
};
+enum {
+ MMU_FTRS_ALWAYS =
+#ifdef CONFIG_PPC_8xx
+ MMU_FTR_TYPE_8xx &
+#endif
+#ifdef CONFIG_40x
+ MMU_FTR_TYPE_40x &
+#endif
+#ifdef CONFIG_PPC_47x
+ MMU_FTR_TYPE_47x &
+#elif defined(CONFIG_44x)
+ MMU_FTR_TYPE_44x &
+#endif
+#if defined(CONFIG_E200) || defined(CONFIG_E500)
+ MMU_FTR_TYPE_FSL_E &
+#endif
+ MMU_FTRS_POSSIBLE,
+};
+
static inline bool early_mmu_has_feature(unsigned long feature)
{
+ if (MMU_FTRS_ALWAYS & feature)
+ return true;
+
return !!(MMU_FTRS_POSSIBLE & cur_cpu_spec->mmu_features & feature);
}
@@ -231,6 +253,9 @@ static __always_inline bool mmu_has_feature(unsigned long feature)
}
#endif
+ if (MMU_FTRS_ALWAYS & feature)
+ return true;
+
if (!(MMU_FTRS_POSSIBLE & feature))
return false;
--
2.25.0
^ permalink raw reply related
* Re: [RFC v1 2/2] KVM: PPC: Book3S HV: abstract secure VM related calls.
From: Bharata B Rao @ 2020-10-12 15:28 UTC (permalink / raw)
To: Ram Pai; +Cc: linuxppc-dev, kvm-ppc, farosas
In-Reply-To: <1602487663-7321-3-git-send-email-linuxram@us.ibm.com>
On Mon, Oct 12, 2020 at 12:27:43AM -0700, Ram Pai wrote:
> Abstract the secure VM related calls into generic calls.
>
> These generic calls will call the corresponding method of the
> backend that prvoides the implementation to support secure VM.
>
> Currently there is only the ultravisor based implementation.
> Modify that implementation to act as a backed to the generic calls.
>
> This plumbing will provide the flexibility to add more backends
> in the future.
>
> Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> ---
> arch/powerpc/include/asm/kvm_book3s_uvmem.h | 100 -----------
> arch/powerpc/include/asm/kvmppc_svm_backend.h | 250 ++++++++++++++++++++++++++
> arch/powerpc/kvm/book3s_64_mmu_radix.c | 6 +-
> arch/powerpc/kvm/book3s_hv.c | 28 +--
> arch/powerpc/kvm/book3s_hv_uvmem.c | 78 ++++++--
> 5 files changed, 327 insertions(+), 135 deletions(-)
> delete mode 100644 arch/powerpc/include/asm/kvm_book3s_uvmem.h
> create mode 100644 arch/powerpc/include/asm/kvmppc_svm_backend.h
>
> diff --git a/arch/powerpc/include/asm/kvmppc_svm_backend.h b/arch/powerpc/include/asm/kvmppc_svm_backend.h
> new file mode 100644
> index 0000000..be60d80
> --- /dev/null
> +++ b/arch/powerpc/include/asm/kvmppc_svm_backend.h
> @@ -0,0 +1,250 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + *
> + * Copyright IBM Corp. 2020
> + *
> + * Authors: Ram Pai <linuxram@us.ibm.com>
> + */
> +
> +#ifndef __POWERPC_KVMPPC_SVM_BACKEND_H__
> +#define __POWERPC_KVMPPC_SVM_BACKEND_H__
> +
> +#include <linux/mutex.h>
> +#include <linux/timer.h>
> +#include <linux/types.h>
> +#include <linux/kvm_types.h>
> +#include <linux/kvm_host.h>
> +#include <linux/bug.h>
> +#ifdef CONFIG_PPC_BOOK3S
> +#include <asm/kvm_book3s.h>
> +#else
> +#include <asm/kvm_booke.h>
> +#endif
> +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
> +#include <asm/paca.h>
> +#include <asm/xive.h>
> +#include <asm/cpu_has_feature.h>
> +#endif
> +
> +struct kvmppc_hmm_backend {
Though we started with HMM initially, what we ended up with eventually
has nothing to do with HMM. Please don't introduce hmm again :-)
> + /* initialize */
> + int (*kvmppc_secmem_init)(void);
> +
> + /* cleanup */
> + void (*kvmppc_secmem_free)(void);
> +
> + /* is memory available */
> + bool (*kvmppc_secmem_available)(void);
> +
> + /* allocate a protected/secure page for the secure VM */
> + unsigned long (*kvmppc_svm_page_in)(struct kvm *kvm,
> + unsigned long gra,
> + unsigned long flags,
> + unsigned long page_shift);
> +
> + /* recover the protected/secure page from the secure VM */
> + unsigned long (*kvmppc_svm_page_out)(struct kvm *kvm,
> + unsigned long gra,
> + unsigned long flags,
> + unsigned long page_shift);
> +
> + /* initiate the transition of a VM to secure VM */
> + unsigned long (*kvmppc_svm_init_start)(struct kvm *kvm);
> +
> + /* finalize the transition of a secure VM */
> + unsigned long (*kvmppc_svm_init_done)(struct kvm *kvm);
> +
> + /* share the page on page fault */
> + int (*kvmppc_svm_page_share)(struct kvm *kvm, unsigned long gfn);
> +
> + /* abort the transition to a secure VM */
> + unsigned long (*kvmppc_svm_init_abort)(struct kvm *kvm);
> +
> + /* add a memory slot */
> + int (*kvmppc_svm_memslot_create)(struct kvm *kvm,
> + const struct kvm_memory_slot *new);
> +
> + /* free a memory slot */
> + void (*kvmppc_svm_memslot_delete)(struct kvm *kvm,
> + const struct kvm_memory_slot *old);
> +
> + /* drop pages allocated to the secure VM */
> + void (*kvmppc_svm_drop_pages)(const struct kvm_memory_slot *free,
> + struct kvm *kvm, bool skip_page_out);
> +};
Since the structure has kvmppc_ prefix, may be you can drop
the same from its members to make the fields smaller?
> +
> +extern const struct kvmppc_hmm_backend *kvmppc_svm_backend;
> +
> +static inline int kvmppc_svm_page_share(struct kvm *kvm, unsigned long gfn)
> +{
> + if (!kvmppc_svm_backend)
> + return -ENODEV;
> +
> + return kvmppc_svm_backend->kvmppc_svm_page_share(kvm,
> + gfn);
> +}
> +
> +static inline void kvmppc_svm_drop_pages(const struct kvm_memory_slot *memslot,
> + struct kvm *kvm, bool skip_page_out)
> +{
> + if (!kvmppc_svm_backend)
> + return;
> +
> + kvmppc_svm_backend->kvmppc_svm_drop_pages(memslot,
> + kvm, skip_page_out);
> +}
> +
> +static inline int kvmppc_svm_page_in(struct kvm *kvm,
> + unsigned long gpa,
> + unsigned long flags,
> + unsigned long page_shift)
> +{
> + if (!kvmppc_svm_backend)
> + return -ENODEV;
> +
> + return kvmppc_svm_backend->kvmppc_svm_page_in(kvm,
> + gpa, flags, page_shift);
> +}
> +
> +static inline int kvmppc_svm_page_out(struct kvm *kvm,
> + unsigned long gpa,
> + unsigned long flags,
> + unsigned long page_shift)
> +{
> + if (!kvmppc_svm_backend)
> + return -ENODEV;
> +
> + return kvmppc_svm_backend->kvmppc_svm_page_out(kvm,
> + gpa, flags, page_shift);
> +}
> +
> +static inline int kvmppc_svm_init_start(struct kvm *kvm)
> +{
> + if (!kvmppc_svm_backend)
> + return -ENODEV;
> +
> + return kvmppc_svm_backend->kvmppc_svm_init_start(kvm);
> +}
> +
> +static inline int kvmppc_svm_init_done(struct kvm *kvm)
> +{
> + if (!kvmppc_svm_backend)
> + return -ENODEV;
> +
> + return kvmppc_svm_backend->kvmppc_svm_init_done(kvm);
> +}
> +
> +static inline int kvmppc_svm_init_abort(struct kvm *kvm)
> +{
> + if (!kvmppc_svm_backend)
> + return -ENODEV;
> +
> + return kvmppc_svm_backend->kvmppc_svm_init_abort(kvm);
> +}
> +
> +static inline void kvmppc_svm_memslot_create(struct kvm *kvm,
> + const struct kvm_memory_slot *memslot)
> +{
> + if (!kvmppc_svm_backend)
> + return;
> +
> + kvmppc_svm_backend->kvmppc_svm_memslot_create(kvm,
> + memslot);
> +}
> +
> +static inline void kvmppc_svm_memslot_delete(struct kvm *kvm,
> + const struct kvm_memory_slot *memslot)
> +{
> + if (!kvmppc_svm_backend)
> + return;
> +
> + kvmppc_svm_backend->kvmppc_svm_memslot_delete(kvm,
> + memslot);
> +}
> +
> +static inline int kvmppc_secmem_init(void)
> +{
> +#ifdef CONFIG_PPC_UV
> + extern const struct kvmppc_hmm_backend kvmppc_uvmem_backend;
> +
> + kvmppc_svm_backend = NULL;
> + if (kvmhv_on_pseries()) {
> + /* @TODO add the protected memory backend */
> + return 0;
> + }
> +
> + kvmppc_svm_backend = &kvmppc_uvmem_backend;
> +
> + if (!kvmppc_svm_backend->kvmppc_secmem_init) {
You have a function named kvmppc_secmem_init() and the field
named the same, can be confusing.
> + pr_err("KVM-HV: kvmppc_svm_backend has no %s\n", __func__);
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_secmem_free) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_secmem_free()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_secmem_available) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_secmem_available()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_page_in) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_page_in()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_page_out) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_page_out()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_init_start) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_init_start()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_init_done) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_init_done()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_page_share) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_page_share()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_init_abort) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_init_abort()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_memslot_create) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_memslot_create()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_memslot_delete) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_memslot_delete()\n");
> + goto err;
> + }
> + if (!kvmppc_svm_backend->kvmppc_svm_drop_pages) {
> + pr_err("KVM-HV: kvmppc_svm_backend has no kvmppc_svm_drop_pages()\n");
> + goto err;
> + }
Do you really need to check each and every callback like above?
If so, may be the check can be optimized?
Regards,
Bharata.
^ permalink raw reply
* Re: [PATCH v5 1/5] powerpc/sstep: Emulate prefixed instructions only when CPU_FTR_ARCH_31 is set
From: Daniel Axtens @ 2020-10-12 13:44 UTC (permalink / raw)
To: Ravi Bangoria, mpe
Cc: ravi.bangoria, jniethe5, bala24, paulus, sandipan, naveen.n.rao,
linuxppc-dev
In-Reply-To: <20201011050908.72173-2-ravi.bangoria@linux.ibm.com>
Hi,
To review this, I looked through the supported instructions to see if
there were any that I thought might have been missed.
I didn't find any other v3.1 ones, although I don't have a v3.1 ISA to
hand so I was basically looking for instructions I didn't recognise.
I did, however, find a number of instructions that are new in ISA 3.0
that aren't guarded:
- addpcis
- lxvl/stxvl
- lxvll/stxvll
- lxvwsx
- stxvx
- lxsipzx
- lxvh8x
- lxsihzx
- lxvb16x/stxvb16x
- stxsibx
- stxsihx
- lxvb16x
- lxsd/stxsd
- lxssp/stxssp
- lxv/stxv
Also, I don't know how bothered we are about P7, but if I'm reading the
ISA correctly, lqarx/stqcx. are not supported before ISA 2.07. Likewise
a number of the vector instructions like lxsiwzx and lxsiwax (and the
companion stores).
I realise it's not really the point of this particular patch, so I don't
think this should block acceptance. What I would like to know - and
maybe this is something where we need mpe to weigh in - is whether we
need consistent guards for 2.07 and 3.0. We have some 3.0 guards already
but clearly not everywhere.
With all that said - the patch does what it says it does, and looks good
to me:
Reviewed-by: Daniel Axtens <dja@axtens.net>
Kind regards,
Daniel
> From: Balamuruhan S <bala24@linux.ibm.com>
>
> Unconditional emulation of prefixed instructions will allow
> emulation of them on Power10 predecessors which might cause
> issues. Restrict that.
>
> Fixes: 3920742b92f5 ("powerpc sstep: Add support for prefixed fixed-point arithmetic")
> Fixes: 50b80a12e4cc ("powerpc sstep: Add support for prefixed load/stores")
> Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
> ---
> arch/powerpc/lib/sstep.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index e9dcaba9a4f8..e6242744c71b 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1346,6 +1346,9 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> switch (opcode) {
> #ifdef __powerpc64__
> case 1:
> + if (!cpu_has_feature(CPU_FTR_ARCH_31))
> + return -1;
> +
> prefix_r = GET_PREFIX_R(word);
> ra = GET_PREFIX_RA(suffix);
> rd = (suffix >> 21) & 0x1f;
> @@ -2733,6 +2736,9 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> }
> break;
> case 1: /* Prefixed instructions */
> + if (!cpu_has_feature(CPU_FTR_ARCH_31))
> + return -1;
> +
> prefix_r = GET_PREFIX_R(word);
> ra = GET_PREFIX_RA(suffix);
> op->update_reg = ra;
> --
> 2.26.2
^ permalink raw reply
* Re: [PATCH v5 1/5] powerpc/sstep: Emulate prefixed instructions only when CPU_FTR_ARCH_31 is set
From: Daniel Axtens @ 2020-10-12 12:55 UTC (permalink / raw)
To: Ravi Bangoria
Cc: Ravi Bangoria, bala24, paulus, sandipan, jniethe5, naveen.n.rao,
linuxppc-dev
In-Reply-To: <41dda593-0fc6-569e-2243-189d84653b4a@linux.ibm.com>
Ravi Bangoria <ravi.bangoria@linux.ibm.com> writes:
> Hi Daniel,
>
> On 10/12/20 7:21 AM, Daniel Axtens wrote:
>> Hi,
>>
>> Apologies if this has come up in a previous revision.
>>
>>
>>> case 1:
>>> + if (!cpu_has_feature(CPU_FTR_ARCH_31))
>>> + return -1;
>>> +
>>> prefix_r = GET_PREFIX_R(word);
>>> ra = GET_PREFIX_RA(suffix);
>>
>> The comment above analyse_instr reads in part:
>>
>> * Return value is 1 if the instruction can be emulated just by
>> * updating *regs with the information in *op, -1 if we need the
>> * GPRs but *regs doesn't contain the full register set, or 0
>> * otherwise.
>>
>> I was wondering why returning -1 if the instruction isn't supported the
>> right thing to do - it seemed to me that it should return 0?
>>
>> I did look and see that there are other cases where the code returns -1
>> for an unsupported operation, e.g.:
>>
>> #ifdef __powerpc64__
>> case 4:
>> if (!cpu_has_feature(CPU_FTR_ARCH_300))
>> return -1;
>>
>> switch (word & 0x3f) {
>> case 48: /* maddhd */
>>
>> That's from commit 930d6288a267 ("powerpc: sstep: Add support for
>> maddhd, maddhdu, maddld instructions"), but it's not explained there either
>>
>> I see the same pattern in a number of commits: commit 6324320de609
>> ("powerpc sstep: Add support for modsd, modud instructions"), commit
>> 6c180071509a ("powerpc sstep: Add support for modsw, moduw
>> instructions"), commit a23987ef267a ("powerpc: sstep: Add support for
>> darn instruction") and a few others, all of which seem to have come
>> through Sandipan in February 2019. I haven't spotted any explanation for
>> why -1 was chosen, but I haven't checked the mailing list archives.
>>
>> If -1 is OK, would it be possible to update the comment to explain why?
>
> Agreed. As you rightly pointed out, there are many more such cases and, yes,
> we are aware of this issue and it's being worked upon as a separate patch.
> (Sandipan did send a fix patch internally some time back).
That sounds like a perfectly reasonable approach.
I'd love to review the patch when it's sent - if you or Sandipan could
please cc: me so I don't miss it I'd really appreciate that.
I will proceed to review the rest of the patch and series.
Kind regards,
Daniel
>
> Thanks for pointing it out!
> Ravi
^ permalink raw reply
* Re: [PATCH] powerpc/perf: fix Threshold Event CounterMultiplier width for P10
From: Michal Suchánek @ 2020-10-12 11:29 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: atrajeev, linuxppc-dev
In-Reply-To: <20201012103128.53243-1-maddy@linux.ibm.com>
Hello,
On Mon, Oct 12, 2020 at 04:01:28PM +0530, Madhavan Srinivasan wrote:
> Power9 and isa v3.1 has 7bit mantissa field for Threshold Event Counter
^^^ Shouldn't his be 3.0?
> Multiplier (TECM). TECM is part of Monitor Mode Control Register A (MMCRA).
> This field along with Threshold Event Counter Exponent (TECE) is used to
> get threshould counter value. In Power10, the width of TECM field is
> increase to 8bits. Patch fixes the current code to modify the MMCRA[TECM]
> extraction macro to handling this changes.
>
> Fixes: 170a315f41c64 ('powerpc/perf: Support to export MMCRA[TEC*] field to userspace')
> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
> ---
> arch/powerpc/perf/isa207-common.c | 3 +++
> arch/powerpc/perf/isa207-common.h | 4 ++++
> 2 files changed, 7 insertions(+)
>
> diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c
> index 964437adec18..5fe129f02290 100644
> --- a/arch/powerpc/perf/isa207-common.c
> +++ b/arch/powerpc/perf/isa207-common.c
> @@ -247,6 +247,9 @@ void isa207_get_mem_weight(u64 *weight)
> u64 sier = mfspr(SPRN_SIER);
> u64 val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT;
>
> + if (cpu_has_feature(CPU_FTR_ARCH_31))
> + mantissa = P10_MMCRA_THR_CTR_MANT(mmcra);
> +
> if (val == 0 || val == 7)
> *weight = 0;
> else
> diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h
> index 044de65e96b9..71380e854f48 100644
> --- a/arch/powerpc/perf/isa207-common.h
> +++ b/arch/powerpc/perf/isa207-common.h
> @@ -219,6 +219,10 @@
> #define MMCRA_THR_CTR_EXP(v) (((v) >> MMCRA_THR_CTR_EXP_SHIFT) &\
> MMCRA_THR_CTR_EXP_MASK)
>
> +#define P10_MMCRA_THR_CTR_MANT_MASK 0xFFul
> +#define P10_MMCRA_THR_CTR_MANT(v) (((v) >> MMCRA_THR_CTR_MANT_SHIFT) &\
> + P10_MMCRA_THR_CTR_MANT_MASK)
> +
> /* MMCRA Threshold Compare bit constant for power9 */
> #define p9_MMCRA_THR_CMP_SHIFT 45
>
> --
> 2.26.2
>
^ permalink raw reply
* Re: [PATCH v5 1/5] powerpc/sstep: Emulate prefixed instructions only when CPU_FTR_ARCH_31 is set
From: Ravi Bangoria @ 2020-10-12 11:07 UTC (permalink / raw)
To: Daniel Axtens
Cc: Ravi Bangoria, bala24, paulus, sandipan, jniethe5, naveen.n.rao,
linuxppc-dev
In-Reply-To: <87h7r0w6s0.fsf@dja-thinkpad.axtens.net>
Hi Daniel,
On 10/12/20 7:21 AM, Daniel Axtens wrote:
> Hi,
>
> Apologies if this has come up in a previous revision.
>
>
>> case 1:
>> + if (!cpu_has_feature(CPU_FTR_ARCH_31))
>> + return -1;
>> +
>> prefix_r = GET_PREFIX_R(word);
>> ra = GET_PREFIX_RA(suffix);
>
> The comment above analyse_instr reads in part:
>
> * Return value is 1 if the instruction can be emulated just by
> * updating *regs with the information in *op, -1 if we need the
> * GPRs but *regs doesn't contain the full register set, or 0
> * otherwise.
>
> I was wondering why returning -1 if the instruction isn't supported the
> right thing to do - it seemed to me that it should return 0?
>
> I did look and see that there are other cases where the code returns -1
> for an unsupported operation, e.g.:
>
> #ifdef __powerpc64__
> case 4:
> if (!cpu_has_feature(CPU_FTR_ARCH_300))
> return -1;
>
> switch (word & 0x3f) {
> case 48: /* maddhd */
>
> That's from commit 930d6288a267 ("powerpc: sstep: Add support for
> maddhd, maddhdu, maddld instructions"), but it's not explained there either
>
> I see the same pattern in a number of commits: commit 6324320de609
> ("powerpc sstep: Add support for modsd, modud instructions"), commit
> 6c180071509a ("powerpc sstep: Add support for modsw, moduw
> instructions"), commit a23987ef267a ("powerpc: sstep: Add support for
> darn instruction") and a few others, all of which seem to have come
> through Sandipan in February 2019. I haven't spotted any explanation for
> why -1 was chosen, but I haven't checked the mailing list archives.
>
> If -1 is OK, would it be possible to update the comment to explain why?
Agreed. As you rightly pointed out, there are many more such cases and, yes,
we are aware of this issue and it's being worked upon as a separate patch.
(Sandipan did send a fix patch internally some time back).
Thanks for pointing it out!
Ravi
^ permalink raw reply
* Re: [PATCH -next v2] powerpc/mm: ptdump: Convert to DEFINE_SHOW_ATTRIBUTE
From: Christophe Leroy @ 2020-10-12 11:02 UTC (permalink / raw)
To: Qinglang Miao, Michael Ellerman, Benjamin Herrenschmidt,
Paul Mackerras
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20200919012901.174233-1-miaoqinglang@huawei.com>
Hi,
Le 19/09/2020 à 03:29, Qinglang Miao a écrit :
> Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.
>
> Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
> ---
> v2: based on linux-next(20200917), and can be applied to
> mainline cleanly now.
After the removal of powerpc 601, this patch needs to be rebased (as of linux-next 20201012)
I think now, bats_show_603() should simply be renamed bats_show()
Christophe
>
> arch/powerpc/mm/ptdump/bats.c | 24 +++++++-----------------
> arch/powerpc/mm/ptdump/hashpagetable.c | 12 +-----------
> arch/powerpc/mm/ptdump/ptdump.c | 13 +------------
> arch/powerpc/mm/ptdump/segment_regs.c | 12 +-----------
> 4 files changed, 10 insertions(+), 51 deletions(-)
>
> diff --git a/arch/powerpc/mm/ptdump/bats.c b/arch/powerpc/mm/ptdump/bats.c
> index e29b338d4..a24495e93 100644
> --- a/arch/powerpc/mm/ptdump/bats.c
> +++ b/arch/powerpc/mm/ptdump/bats.c
> @@ -56,7 +56,7 @@ static void bat_show_601(struct seq_file *m, int idx, u32 lower, u32 upper)
>
> #define BAT_SHOW_601(_m, _n, _l, _u) bat_show_601(_m, _n, mfspr(_l), mfspr(_u))
>
> -static int bats_show_601(struct seq_file *m, void *v)
> +static int bats_601_show(struct seq_file *m, void *v)
> {
> seq_puts(m, "---[ Block Address Translation ]---\n");
>
> @@ -113,7 +113,7 @@ static void bat_show_603(struct seq_file *m, int idx, u32 lower, u32 upper, bool
>
> #define BAT_SHOW_603(_m, _n, _l, _u, _d) bat_show_603(_m, _n, mfspr(_l), mfspr(_u), _d)
>
> -static int bats_show_603(struct seq_file *m, void *v)
> +static int bats_603_show(struct seq_file *m, void *v)
> {
> seq_puts(m, "---[ Instruction Block Address Translation ]---\n");
>
> @@ -144,25 +144,15 @@ static int bats_show_603(struct seq_file *m, void *v)
> return 0;
> }
>
> -static int bats_open(struct inode *inode, struct file *file)
> -{
> - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
> - return single_open(file, bats_show_601, NULL);
> -
> - return single_open(file, bats_show_603, NULL);
> -}
> -
> -static const struct file_operations bats_fops = {
> - .open = bats_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> -};
> +DEFINE_SHOW_ATTRIBUTE(bats_601);
> +DEFINE_SHOW_ATTRIBUTE(bats_603);
>
> static int __init bats_init(void)
> {
> debugfs_create_file("block_address_translation", 0400,
> - powerpc_debugfs_root, NULL, &bats_fops);
> + powerpc_debugfs_root, NULL,
> + IS_ENABLED(CONFIG_PPC_BOOK3S_601) ?
> + &bats_601_fops : & bats_603_fops);
> return 0;
> }
> device_initcall(bats_init);
> diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c
> index ad6df9a2e..c7f824d29 100644
> --- a/arch/powerpc/mm/ptdump/hashpagetable.c
> +++ b/arch/powerpc/mm/ptdump/hashpagetable.c
> @@ -526,17 +526,7 @@ static int ptdump_show(struct seq_file *m, void *v)
> return 0;
> }
>
> -static int ptdump_open(struct inode *inode, struct file *file)
> -{
> - return single_open(file, ptdump_show, NULL);
> -}
> -
> -static const struct file_operations ptdump_fops = {
> - .open = ptdump_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> -};
> +DEFINE_SHOW_ATTRIBUTE(ptdump);
>
> static int ptdump_init(void)
> {
> diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
> index aca354fb6..6bbf85ff2 100644
> --- a/arch/powerpc/mm/ptdump/ptdump.c
> +++ b/arch/powerpc/mm/ptdump/ptdump.c
> @@ -413,18 +413,7 @@ static int ptdump_show(struct seq_file *m, void *v)
> return 0;
> }
>
> -
> -static int ptdump_open(struct inode *inode, struct file *file)
> -{
> - return single_open(file, ptdump_show, NULL);
> -}
> -
> -static const struct file_operations ptdump_fops = {
> - .open = ptdump_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> -};
> +DEFINE_SHOW_ATTRIBUTE(ptdump);
>
> static void build_pgtable_complete_mask(void)
> {
> diff --git a/arch/powerpc/mm/ptdump/segment_regs.c b/arch/powerpc/mm/ptdump/segment_regs.c
> index dde2fe8de..9e870d44c 100644
> --- a/arch/powerpc/mm/ptdump/segment_regs.c
> +++ b/arch/powerpc/mm/ptdump/segment_regs.c
> @@ -41,17 +41,7 @@ static int sr_show(struct seq_file *m, void *v)
> return 0;
> }
>
> -static int sr_open(struct inode *inode, struct file *file)
> -{
> - return single_open(file, sr_show, NULL);
> -}
> -
> -static const struct file_operations sr_fops = {
> - .open = sr_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> -};
> +DEFINE_SHOW_ATTRIBUTE(sr);
>
> static int __init sr_init(void)
> {
>
^ permalink raw reply
* [PATCH] powerpc/perf: fix Threshold Event CounterMultiplier width for P10
From: Madhavan Srinivasan @ 2020-10-12 10:31 UTC (permalink / raw)
To: mpe; +Cc: atrajeev, linuxppc-dev, Madhavan Srinivasan
Power9 and isa v3.1 has 7bit mantissa field for Threshold Event Counter
Multiplier (TECM). TECM is part of Monitor Mode Control Register A (MMCRA).
This field along with Threshold Event Counter Exponent (TECE) is used to
get threshould counter value. In Power10, the width of TECM field is
increase to 8bits. Patch fixes the current code to modify the MMCRA[TECM]
extraction macro to handling this changes.
Fixes: 170a315f41c64 ('powerpc/perf: Support to export MMCRA[TEC*] field to userspace')
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
---
arch/powerpc/perf/isa207-common.c | 3 +++
arch/powerpc/perf/isa207-common.h | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c
index 964437adec18..5fe129f02290 100644
--- a/arch/powerpc/perf/isa207-common.c
+++ b/arch/powerpc/perf/isa207-common.c
@@ -247,6 +247,9 @@ void isa207_get_mem_weight(u64 *weight)
u64 sier = mfspr(SPRN_SIER);
u64 val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT;
+ if (cpu_has_feature(CPU_FTR_ARCH_31))
+ mantissa = P10_MMCRA_THR_CTR_MANT(mmcra);
+
if (val == 0 || val == 7)
*weight = 0;
else
diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h
index 044de65e96b9..71380e854f48 100644
--- a/arch/powerpc/perf/isa207-common.h
+++ b/arch/powerpc/perf/isa207-common.h
@@ -219,6 +219,10 @@
#define MMCRA_THR_CTR_EXP(v) (((v) >> MMCRA_THR_CTR_EXP_SHIFT) &\
MMCRA_THR_CTR_EXP_MASK)
+#define P10_MMCRA_THR_CTR_MANT_MASK 0xFFul
+#define P10_MMCRA_THR_CTR_MANT(v) (((v) >> MMCRA_THR_CTR_MANT_SHIFT) &\
+ P10_MMCRA_THR_CTR_MANT_MASK)
+
/* MMCRA Threshold Compare bit constant for power9 */
#define p9_MMCRA_THR_CMP_SHIFT 45
--
2.26.2
^ permalink raw reply related
* [PATCH v2 1/2] powerpc/8xx: Always fault when _PAGE_ACCESSED is not set
From: Christophe Leroy @ 2020-10-12 8:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
The kernel expects pte_young() to work regardless of CONFIG_SWAP.
Make sure a minor fault is taken to set _PAGE_ACCESSED when it
is not already set, regardless of the selection of CONFIG_SWAP.
This adds at least 3 instructions to the TLB miss exception
handlers fast path. Following patch will reduce this overhead.
Also update the rotation instruction to the correct number of bits
to reflect all changes done to _PAGE_ACCESSED over time.
Fixes: d069cb4373fe ("powerpc/8xx: Don't touch ACCESSED when no SWAP.")
Fixes: 5f356497c384 ("powerpc/8xx: remove unused _PAGE_WRITETHRU")
Fixes: e0a8e0d90a9f ("powerpc/8xx: Handle PAGE_USER via APG bits")
Fixes: 5b2753fc3e8a ("powerpc/8xx: Implementation of PAGE_EXEC")
Fixes: a891c43b97d3 ("powerpc/8xx: Prepare handlers for _PAGE_HUGE for 512k pages.")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
v2: Backporting to stable will have to be done manually. Squashed
the first 3 patches in order to ease that backporting.
---
arch/powerpc/kernel/head_8xx.S | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 9f359d3fba74..6f3799a04121 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -202,9 +202,7 @@ SystemCall:
InstructionTLBMiss:
mtspr SPRN_SPRG_SCRATCH0, r10
-#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS)
mtspr SPRN_SPRG_SCRATCH1, r11
-#endif
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
@@ -238,11 +236,9 @@ InstructionTLBMiss:
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
mtspr SPRN_MI_TWC, r11
#endif
-#ifdef CONFIG_SWAP
- rlwinm r11, r10, 32-5, _PAGE_PRESENT
+ rlwinm r11, r10, 32-7, _PAGE_PRESENT
and r11, r11, r10
rlwimi r10, r11, 0, _PAGE_PRESENT
-#endif
/* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 20 and 23 must be clear.
* Software indicator bits 22, 24, 25, 26, and 27 must be
@@ -256,9 +252,7 @@ InstructionTLBMiss:
/* Restore registers */
0: mfspr r10, SPRN_SPRG_SCRATCH0
-#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS)
mfspr r11, SPRN_SPRG_SCRATCH1
-#endif
rfi
patch_site 0b, patch__itlbmiss_exit_1
@@ -268,9 +262,7 @@ InstructionTLBMiss:
addi r10, r10, 1
stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0)
mfspr r10, SPRN_SPRG_SCRATCH0
-#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
mfspr r11, SPRN_SPRG_SCRATCH1
-#endif
rfi
#endif
@@ -316,11 +308,9 @@ DataStoreTLBMiss:
* r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
* r10 = (r10 & ~PRESENT) | r11;
*/
-#ifdef CONFIG_SWAP
- rlwinm r11, r10, 32-5, _PAGE_PRESENT
+ rlwinm r11, r10, 32-7, _PAGE_PRESENT
and r11, r11, r10
rlwimi r10, r11, 0, _PAGE_PRESENT
-#endif
/* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 24, 25, 26, and 27 must be
* set. All other Linux PTE bits control the behavior
--
2.25.0
^ permalink raw reply related
* [PATCH v2 2/2] powerpc/8xx: Manage _PAGE_ACCESSED through APG bits in L1 entry
From: Christophe Leroy @ 2020-10-12 8:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <af834e8a0f1fa97bfae65664950f0984a70c4750.1602492856.git.christophe.leroy@csgroup.eu>
When _PAGE_ACCESSED is not set, a minor fault is expected.
To do this, TLB miss exception ANDs _PAGE_PRESENT and _PAGE_ACCESSED
into the L2 entry valid bit.
To simplify the processing and reduce the number of instructions in
TLB miss exceptions, manage it as an APG bit and get it next to
_PAGE_GUARDED bit to allow a copy in one go. Then declare the
corresponding groups as handling all accesses as user accesses.
As the PP bits always define user as No Access, it will generate
a fault.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/nohash/32/kup-8xx.h | 2 +-
arch/powerpc/include/asm/nohash/32/mmu-8xx.h | 47 +++++++-------------
arch/powerpc/include/asm/nohash/32/pte-8xx.h | 9 ++--
arch/powerpc/kernel/head_8xx.S | 36 +++------------
4 files changed, 28 insertions(+), 66 deletions(-)
diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/include/asm/nohash/32/kup-8xx.h
index 85ed2390fb99..567cdc557402 100644
--- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h
@@ -63,7 +63,7 @@ static inline void restore_user_access(unsigned long flags)
static inline bool
bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
{
- return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000),
+ return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xff000000),
"Bug: fault blocked by AP register !");
}
diff --git a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
index 1d9ac0f9c794..0bd1b144eb76 100644
--- a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
@@ -33,19 +33,18 @@
* respectively NA for All or X for Supervisor and no access for User.
* Then we use the APG to say whether accesses are according to Page rules or
* "all Supervisor" rules (Access to all)
- * Therefore, we define 2 APG groups. lsb is _PMD_USER
- * 0 => Kernel => 01 (all accesses performed according to page definition)
- * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
- * 2-15 => Not Used
- */
-#define MI_APG_INIT 0x40000000
-
-/*
- * 0 => Kernel => 01 (all accesses performed according to page definition)
- * 1 => User => 10 (all accesses performed according to swaped page definition)
- * 2-15 => Not Used
- */
-#define MI_APG_KUEP 0x60000000
+ * _PAGE_ACCESSED is also managed via APG. When _PAGE_ACCESSED is not set, say
+ * "all User" rules, that will lead to NA for all.
+ * Therefore, we define 4 APG groups. lsb is _PAGE_ACCESSED
+ * 0 => Kernel => 11 (all accesses performed according as user iaw page definition)
+ * 1 => Kernel+Accessed => 01 (all accesses performed according to page definition)
+ * 2 => User => 11 (all accesses performed according as user iaw page definition)
+ * 3 => User+Accessed => 00 (all accesses performed as supervisor iaw page definition) for INIT
+ * => 10 (all accesses performed according to swaped page definition) for KUEP
+ * 4-15 => Not Used
+ */
+#define MI_APG_INIT 0xdc000000
+#define MI_APG_KUEP 0xde000000
/* The effective page number register. When read, contains the information
* about the last instruction TLB miss. When MI_RPN is written, bits in
@@ -106,25 +105,9 @@
#define MD_Ks 0x80000000 /* Should not be set */
#define MD_Kp 0x40000000 /* Should always be set */
-/*
- * All pages' PP data bits are set to either 000 or 011 or 001, which means
- * respectively RW for Supervisor and no access for User, or RO for
- * Supervisor and no access for user and NA for ALL.
- * Then we use the APG to say whether accesses are according to Page rules or
- * "all Supervisor" rules (Access to all)
- * Therefore, we define 2 APG groups. lsb is _PMD_USER
- * 0 => Kernel => 01 (all accesses performed according to page definition)
- * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
- * 2-15 => Not Used
- */
-#define MD_APG_INIT 0x40000000
-
-/*
- * 0 => No user => 01 (all accesses performed according to page definition)
- * 1 => User => 10 (all accesses performed according to swaped page definition)
- * 2-15 => Not Used
- */
-#define MD_APG_KUAP 0x60000000
+/* See explanation above at the definition of MI_APG_INIT */
+#define MD_APG_INIT 0xdc000000
+#define MD_APG_KUAP 0xde000000
/* The effective page number register. When read, contains the information
* about the last instruction TLB miss. When MD_RPN is written, bits in
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index 66f403a7da44..1581204467e1 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -39,9 +39,9 @@
* into the TLB.
*/
#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */
-#define _PAGE_SPECIAL 0x0020 /* SW entry */
+#define _PAGE_ACCESSED 0x0020 /* Copied to L1 APG 1 entry in I/DTLB */
#define _PAGE_EXEC 0x0040 /* Copied to PP (bit 21) in ITLB */
-#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
+#define _PAGE_SPECIAL 0x0080 /* SW entry */
#define _PAGE_NA 0x0200 /* Supervisor NA, User no access */
#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
@@ -59,11 +59,12 @@
#define _PMD_PRESENT 0x0001
#define _PMD_PRESENT_MASK _PMD_PRESENT
-#define _PMD_BAD 0x0fd0
+#define _PMD_BAD 0x0f90
#define _PMD_PAGE_MASK 0x000c
#define _PMD_PAGE_8M 0x000c
#define _PMD_PAGE_512K 0x0004
-#define _PMD_USER 0x0020 /* APG 1 */
+#define _PMD_ACCESSED 0x0020 /* APG 1 */
+#define _PMD_USER 0x0040 /* APG 2 */
#define _PTE_NONE_MASK 0
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 6f3799a04121..ee0bfebc375f 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -222,23 +222,13 @@ InstructionTLBMiss:
3:
mtcr r11
#endif
-#if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT)
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
mtspr SPRN_MD_TWC, r11
-#else
- lwz r10, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
- mtspr SPRN_MI_TWC, r10 /* Set segment attributes */
- mtspr SPRN_MD_TWC, r10
-#endif
mfspr r10, SPRN_MD_TWC
lwz r10, 0(r10) /* Get the pte */
-#if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT)
+ rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
mtspr SPRN_MI_TWC, r11
-#endif
- rlwinm r11, r10, 32-7, _PAGE_PRESENT
- and r11, r11, r10
- rlwimi r10, r11, 0, _PAGE_PRESENT
/* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 20 and 23 must be clear.
* Software indicator bits 22, 24, 25, 26, and 27 must be
@@ -289,28 +279,16 @@ DataStoreTLBMiss:
mfspr r10, SPRN_MD_TWC
lwz r10, 0(r10) /* Get the pte */
- /* Insert the Guarded flag into the TWC from the Linux PTE.
+ /* Insert Guarded and Accessed flags into the TWC from the Linux PTE.
* It is bit 27 of both the Linux PTE and the TWC (at least
* I got that right :-). It will be better when we can put
* this into the Linux pgd/pmd and load it in the operation
* above.
*/
- rlwimi r11, r10, 0, _PAGE_GUARDED
+ rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
mtspr SPRN_MD_TWC, r11
- /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
- * We also need to know if the insn is a load/store, so:
- * Clear _PAGE_PRESENT and load that which will
- * trap into DTLB Error with store bit set accordinly.
- */
- /* PRESENT=0x1, ACCESSED=0x20
- * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
- * r10 = (r10 & ~PRESENT) | r11;
- */
- rlwinm r11, r10, 32-7, _PAGE_PRESENT
- and r11, r11, r10
- rlwimi r10, r11, 0, _PAGE_PRESENT
/* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 24, 25, 26, and 27 must be
* set. All other Linux PTE bits control the behavior
@@ -701,7 +679,7 @@ initial_mmu:
li r9, 4 /* up to 4 pages of 8M */
mtctr r9
lis r9, KERNELBASE@h /* Create vaddr for TLB */
- li r10, MI_PS8MEG | MI_SVALID /* Set 8M byte page */
+ li r10, MI_PS8MEG | _PMD_ACCESSED | MI_SVALID
li r11, MI_BOOTINIT /* Create RPN for address 0 */
1:
mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
@@ -765,7 +743,7 @@ _GLOBAL(mmu_pin_tlb)
#ifdef CONFIG_PIN_TLB_TEXT
LOAD_REG_IMMEDIATE(r5, 28 << 8)
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
- LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG)
+ LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED)
LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
LOAD_REG_ADDR(r9, _sinittext)
li r0, 4
@@ -787,7 +765,7 @@ _GLOBAL(mmu_pin_tlb)
LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM)
#ifdef CONFIG_PIN_TLB_DATA
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
- LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG)
+ LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED)
#ifdef CONFIG_PIN_TLB_IMMR
li r0, 3
#else
@@ -824,7 +802,7 @@ _GLOBAL(mmu_pin_tlb)
#endif
#ifdef CONFIG_PIN_TLB_IMMR
LOAD_REG_IMMEDIATE(r0, VIRT_IMMR_BASE | MD_EVALID)
- LOAD_REG_IMMEDIATE(r7, MD_SVALID | MD_PS512K | MD_GUARDED)
+ LOAD_REG_IMMEDIATE(r7, MD_SVALID | MD_PS512K | MD_GUARDED | _PMD_ACCESSED)
mfspr r8, SPRN_IMMR
rlwinm r8, r8, 0, 0xfff80000
ori r8, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | \
--
2.25.0
^ permalink raw reply related
* [PATCH] ASoC: fsl_spdif: Add support for higher sample rates
From: Shengjiu Wang @ 2020-10-12 8:49 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel
Cc: linuxppc-dev, linux-kernel
Add 88200Hz and 176400Hz sample rates support for TX.
Add 88200Hz, 176400Hz, 192000Hz sample rates support for RX.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
---
sound/soc/fsl/fsl_spdif.c | 16 +++++++++++++---
sound/soc/fsl/fsl_spdif.h | 9 ++++++++-
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index b0f643fefe1e..f41496cf5b63 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -429,10 +429,18 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
rate = SPDIF_TXRATE_48000;
csfs = IEC958_AES3_CON_FS_48000;
break;
+ case 88200:
+ rate = SPDIF_TXRATE_88200;
+ csfs = IEC958_AES3_CON_FS_88200;
+ break;
case 96000:
rate = SPDIF_TXRATE_96000;
csfs = IEC958_AES3_CON_FS_96000;
break;
+ case 176400:
+ rate = SPDIF_TXRATE_176400;
+ csfs = IEC958_AES3_CON_FS_176400;
+ break;
case 192000:
rate = SPDIF_TXRATE_192000;
csfs = IEC958_AES3_CON_FS_192000;
@@ -827,7 +835,7 @@ static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
uinfo->value.integer.min = 16000;
- uinfo->value.integer.max = 96000;
+ uinfo->value.integer.max = 192000;
return 0;
}
@@ -1145,7 +1153,8 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
struct clk *clk, u64 savesub,
enum spdif_txrate index, bool round)
{
- static const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
+ static const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400,
+ 192000, };
bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
u64 rate_ideal, rate_actual, sub;
u32 arate;
@@ -1205,7 +1214,8 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
enum spdif_txrate index)
{
- static const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
+ static const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400,
+ 192000, };
struct platform_device *pdev = spdif_priv->pdev;
struct device *dev = &pdev->dev;
u64 savesub = 100000, ret;
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h
index e6c61e07bc1a..d5f1dfd58740 100644
--- a/sound/soc/fsl/fsl_spdif.h
+++ b/sound/soc/fsl/fsl_spdif.h
@@ -163,7 +163,9 @@ enum spdif_txrate {
SPDIF_TXRATE_32000 = 0,
SPDIF_TXRATE_44100,
SPDIF_TXRATE_48000,
+ SPDIF_TXRATE_88200,
SPDIF_TXRATE_96000,
+ SPDIF_TXRATE_176400,
SPDIF_TXRATE_192000,
};
#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_192000 + 1)
@@ -177,15 +179,20 @@ enum spdif_txrate {
#define FSL_SPDIF_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_88200 | \
SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_176400 | \
SNDRV_PCM_RATE_192000)
#define FSL_SPDIF_RATES_CAPTURE (SNDRV_PCM_RATE_16000 | \
SNDRV_PCM_RATE_32000 | \
SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_88200 | \
SNDRV_PCM_RATE_64000 | \
- SNDRV_PCM_RATE_96000)
+ SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_176400 | \
+ SNDRV_PCM_RATE_192000)
#define FSL_SPDIF_FORMATS_PLAYBACK (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \
--
2.27.0
^ permalink raw reply related
* [PATCH 2/2] powerpc/44x: Don't support 47x code and non 47x code at the same time
From: Christophe Leroy @ 2020-10-12 8:07 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <181da5d3c4f07dca6662cdc7c72d81297eef5f1e.1602490050.git.christophe.leroy@csgroup.eu>
440/460 variants and 470 variants are not compatible, no
need to make code supporting both and using MMU features.
Just use CONFIG_PPC_47x to decide what to build.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/entry_32.S | 11 +++--------
arch/powerpc/mm/nohash/tlb_low.S | 29 +++++++----------------------
2 files changed, 10 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 8cdc8bcde703..a7727006d6f5 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -439,15 +439,13 @@ syscall_exit_cont:
andis. r10,r0,DBCR0_IDM@h
bnel- load_dbcr0
#endif
-#ifdef CONFIG_44x
-BEGIN_MMU_FTR_SECTION
+#ifdef CONFIG_PPC_47x
lis r4,icache_44x_need_flush@ha
lwz r5,icache_44x_need_flush@l(r4)
cmplwi cr0,r5,0
bne- 2f
1:
-END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_47x)
-#endif /* CONFIG_44x */
+#endif /* CONFIG_PPC_47x */
BEGIN_FTR_SECTION
lwarx r7,0,r1
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
@@ -948,10 +946,7 @@ restore_kuap:
/* interrupts are hard-disabled at this point */
restore:
-#ifdef CONFIG_44x
-BEGIN_MMU_FTR_SECTION
- b 1f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
+#if defined(CONFIG_44x) && !defined(CONFIG_PPC_47x)
lis r4,icache_44x_need_flush@ha
lwz r5,icache_44x_need_flush@l(r4)
cmplwi cr0,r5,0
diff --git a/arch/powerpc/mm/nohash/tlb_low.S b/arch/powerpc/mm/nohash/tlb_low.S
index eaeee402f96e..68797e072f55 100644
--- a/arch/powerpc/mm/nohash/tlb_low.S
+++ b/arch/powerpc/mm/nohash/tlb_low.S
@@ -92,36 +92,25 @@ _GLOBAL(__tlbil_va)
tlbsx. r6,0,r3
bne 10f
sync
-BEGIN_MMU_FTR_SECTION
- b 2f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
+#ifndef CONFIG_PPC_47x
/* On 440 There are only 64 TLB entries, so r3 < 64, which means bit
* 22, is clear. Since 22 is the V bit in the TLB_PAGEID, loading this
* value will invalidate the TLB entry.
*/
tlbwe r6,r6,PPC44x_TLB_PAGEID
- isync
-10: wrtee r10
- blr
-2:
-#ifdef CONFIG_PPC_47x
+#else
oris r7,r6,0x8000 /* specify way explicitly */
clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */
ori r4,r4,PPC47x_TLBE_SIZE
tlbwe r4,r7,0 /* write it */
+#endif /* !CONFIG_PPC_47x */
isync
- wrtee r10
+10: wrtee r10
blr
-#else /* CONFIG_PPC_47x */
-1: trap
- EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0;
-#endif /* !CONFIG_PPC_47x */
_GLOBAL(_tlbil_all)
_GLOBAL(_tlbil_pid)
-BEGIN_MMU_FTR_SECTION
- b 2f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
+#ifndef CONFIG_PPC_47x
li r3,0
sync
@@ -136,8 +125,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
isync
blr
-2:
-#ifdef CONFIG_PPC_47x
+#else
/* 476 variant. There's not simple way to do this, hopefully we'll
* try to limit the amount of such full invalidates
*/
@@ -179,11 +167,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
b 1b /* Then loop */
1: isync /* Sync shadows */
wrtee r11
-#else /* CONFIG_PPC_47x */
-1: trap
- EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0;
-#endif /* !CONFIG_PPC_47x */
blr
+#endif /* !CONFIG_PPC_47x */
#ifdef CONFIG_PPC_47x
--
2.25.0
^ permalink raw reply related
* [PATCH 1/2] powerpc/44x: Don't support 440 when CONFIG_PPC_47x is set
From: Christophe Leroy @ 2020-10-12 8:07 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
As stated in platform/44x/Kconfig, CONFIG_PPC_47x is not
compatible with 440 and 460 variants.
This is confirmed in asm/cache.h as L1_CACHE_SHIFT is different
for 47x, meaning a kernel built for 47x will not run correctly
on a 440.
In cputable, opt out all 440 and 460 variants when CONFIG_PPC_47x
is set. Also add a default match dedicated to 470.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/cputable.h | 9 +++++----
arch/powerpc/include/asm/mmu.h | 7 +++----
arch/powerpc/kernel/cputable.c | 29 +++++++++++++++++++++--------
3 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index d88bcb79f16d..4a0ddf66bd4a 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -523,11 +523,10 @@ enum {
#ifdef CONFIG_40x
CPU_FTRS_40X |
#endif
-#ifdef CONFIG_44x
- CPU_FTRS_44X | CPU_FTRS_440x6 |
-#endif
#ifdef CONFIG_PPC_47x
CPU_FTRS_47X | CPU_FTR_476_DD2 |
+#elif defined(CONFIG_44x)
+ CPU_FTRS_44X | CPU_FTRS_440x6 |
#endif
#ifdef CONFIG_E200
CPU_FTRS_E200 |
@@ -596,7 +595,9 @@ enum {
#ifdef CONFIG_40x
CPU_FTRS_40X &
#endif
-#ifdef CONFIG_44x
+#ifdef CONFIG_PPC_47x
+ CPU_FTRS_47X &
+#elif defined(CONFIG_44x)
CPU_FTRS_44X & CPU_FTRS_440x6 &
#endif
#ifdef CONFIG_E200
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 097f23c28c68..49d2c09b7175 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -162,15 +162,14 @@ enum {
#ifdef CONFIG_40x
MMU_FTR_TYPE_40x |
#endif
-#ifdef CONFIG_44x
+#ifdef CONFIG_PPC_47x
+ MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL |
+#elif defined(CONFIG_44x)
MMU_FTR_TYPE_44x |
#endif
#if defined(CONFIG_E200) || defined(CONFIG_E500)
MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | MMU_FTR_USE_TLBILX |
#endif
-#ifdef CONFIG_PPC_47x
- MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL |
-#endif
#ifdef CONFIG_PPC_BOOK3S_32
MMU_FTR_USE_HIGH_BATS |
#endif
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 492c0b36aff6..cf80e6c8ed5e 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1533,6 +1533,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
#endif /* CONFIG_40x */
#ifdef CONFIG_44x
+#ifndef CONFIG_PPC_47x
{
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000850,
@@ -1815,7 +1816,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_440A,
.platform = "ppc440",
},
-#ifdef CONFIG_PPC_47x
+ { /* default match */
+ .pvr_mask = 0x00000000,
+ .pvr_value = 0x00000000,
+ .cpu_name = "(generic 44x PPC)",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE,
+ .mmu_features = MMU_FTR_TYPE_44x,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .machine_check = machine_check_4xx,
+ .platform = "ppc440",
+ }
+#else /* CONFIG_PPC_47x */
{ /* 476 DD2 core */
.pvr_mask = 0xffffffff,
.pvr_value = 0x11a52080,
@@ -1872,19 +1885,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_47x,
.platform = "ppc470",
},
-#endif /* CONFIG_PPC_47x */
{ /* default match */
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
- .cpu_name = "(generic 44x PPC)",
- .cpu_features = CPU_FTRS_44X,
+ .cpu_name = "(generic 47x PPC)",
+ .cpu_features = CPU_FTRS_47X,
.cpu_user_features = COMMON_USER_BOOKE,
- .mmu_features = MMU_FTR_TYPE_44x,
+ .mmu_features = MMU_FTR_TYPE_47x,
.icache_bsize = 32,
- .dcache_bsize = 32,
- .machine_check = machine_check_4xx,
- .platform = "ppc440",
+ .dcache_bsize = 128,
+ .machine_check = machine_check_47x,
+ .platform = "ppc470",
}
+#endif /* CONFIG_PPC_47x */
#endif /* CONFIG_44x */
#ifdef CONFIG_E200
{ /* e200z5 */
--
2.25.0
^ permalink raw reply related
* [PATCH] powerpc/mm: Add mask of always present MMU features
From: Christophe Leroy @ 2020-10-12 8:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
On the same principle as commit 773edeadf672 ("powerpc/mm: Add mask
of possible MMU features"), add mask for MMU features that are
always there in order to optimise out dead branches.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/mmu.h | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index d134f8f8099f..097f23c28c68 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -203,8 +203,30 @@ enum {
0,
};
+enum {
+ MMU_FTRS_ALWAYS =
+#ifdef CONFIG_PPC_8xx
+ MMU_FTR_TYPE_8xx &
+#endif
+#ifdef CONFIG_40x
+ MMU_FTR_TYPE_40x &
+#endif
+#ifdef CONFIG_PPC_47x
+ MMU_FTR_TYPE_47x &
+#elif defined(CONFIG_44x)
+ MMU_FTR_TYPE_44x &
+#endif
+#if defined(CONFIG_E200) || defined(CONFIG_E500)
+ MMU_FTR_TYPE_FSL_E &
+#endif
+ ~0,
+};
+
static inline bool early_mmu_has_feature(unsigned long feature)
{
+ if (MMU_FTRS_ALWAYS & feature)
+ return true;
+
return !!(MMU_FTRS_POSSIBLE & cur_cpu_spec->mmu_features & feature);
}
@@ -233,6 +255,9 @@ static __always_inline bool mmu_has_feature(unsigned long feature)
}
#endif
+ if (MMU_FTRS_ALWAYS & feature)
+ return true;
+
if (!(MMU_FTRS_POSSIBLE & feature))
return false;
--
2.25.0
^ permalink raw reply related
* [PATCH] powerpc/mm: MMU_FTR_NEED_DTLB_SW_LRU is only possible with CONFIG_PPC_83xx
From: Christophe Leroy @ 2020-10-12 8:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
Only mpc83xx will set MMU_FTR_NEED_DTLB_SW_LRU and its
definition is enclosed in #ifdef CONFIG_PPC_83xx.
Make MMU_FTR_NEED_DTLB_SW_LRU possible only when
CONFIG_PPC_83xx is set.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/mmu.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index b4367fd0b477..d134f8f8099f 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -172,7 +172,10 @@ enum {
MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL |
#endif
#ifdef CONFIG_PPC_BOOK3S_32
- MMU_FTR_USE_HIGH_BATS | MMU_FTR_NEED_DTLB_SW_LRU |
+ MMU_FTR_USE_HIGH_BATS |
+#endif
+#ifdef CONFIG_PPC_83xx
+ MMU_FTR_NEED_DTLB_SW_LRU |
#endif
#ifdef CONFIG_PPC_BOOK3E_64
MMU_FTR_USE_TLBRSRV | MMU_FTR_USE_PAIRED_MAS |
--
2.25.0
^ permalink raw reply related
* [PATCH] powerpc/mm: Desintegrate MMU_FTR_PPCAS_ARCH_V2
From: Christophe Leroy @ 2020-10-12 8:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
MMU_FTR_PPCAS_ARCH_V2 is defined in cpu_table.h
as MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE.
MMU_FTR_TLBIEL and MMU_FTR_16M_PAGE are defined in mmu.h
MMU_FTR_PPCAS_ARCH_V2 is used only in mmu.h and it is used only once.
Remove MMU_FTR_PPCAS_ARCH_V2 and use
directly MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/cputable.h | 2 --
arch/powerpc/include/asm/mmu.h | 3 +--
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index accdc1286f37..d88bcb79f16d 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -220,8 +220,6 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE)
-#define MMU_FTR_PPCAS_ARCH_V2 (MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE)
-
/* We only set the altivec features if the kernel was compiled with altivec
* support
*/
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 255a1837e9f7..b4367fd0b477 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -126,8 +126,7 @@
#define MMU_FTR_RADIX_KUAP ASM_CONST(0x80000000)
/* MMU feature bit sets for various CPUs */
-#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \
- MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
+#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 (MMU_FTR_HPTE_TABLE | MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE)
#define MMU_FTRS_POWER MMU_FTRS_DEFAULT_HPTE_ARCH_V2
#define MMU_FTRS_PPC970 MMU_FTRS_POWER | MMU_FTR_TLBIE_CROP_VA
#define MMU_FTRS_POWER5 MMU_FTRS_POWER | MMU_FTR_LOCKLESS_TLBIE
--
2.25.0
^ permalink raw reply related
* [PATCH] powerpc/features: Remove CPU_FTR_NODSISRALIGN
From: Christophe Leroy @ 2020-10-12 8:03 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
CPU_FTR_NODSISRALIGN has not been used since
commit 31bfdb036f12 ("powerpc: Use instruction emulation
infrastructure to handle alignment faults")
Remove it.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/cputable.h | 22 ++++++++++------------
arch/powerpc/kernel/dt_cpu_ftrs.c | 8 --------
arch/powerpc/kernel/prom.c | 2 +-
3 files changed, 11 insertions(+), 21 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 9780c55f9811..accdc1286f37 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -137,7 +137,6 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_DBELL ASM_CONST(0x00000004)
#define CPU_FTR_CAN_NAP ASM_CONST(0x00000008)
#define CPU_FTR_DEBUG_LVL_EXC ASM_CONST(0x00000010)
-#define CPU_FTR_NODSISRALIGN ASM_CONST(0x00000020)
#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x00000040)
#define CPU_FTR_LWSYNC ASM_CONST(0x00000080)
#define CPU_FTR_NOEXECUTE ASM_CONST(0x00000100)
@@ -219,7 +218,7 @@ static inline void cpu_feature_keys_init(void) { }
#ifndef __ASSEMBLY__
-#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN)
+#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE)
#define MMU_FTR_PPCAS_ARCH_V2 (MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE)
@@ -378,33 +377,33 @@ static inline void cpu_feature_keys_init(void) { }
CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON)
#define CPU_FTRS_8XX (CPU_FTR_NOEXECUTE)
-#define CPU_FTRS_40X (CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
-#define CPU_FTRS_44X (CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
-#define CPU_FTRS_440x6 (CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE | \
+#define CPU_FTRS_40X (CPU_FTR_NOEXECUTE)
+#define CPU_FTRS_44X (CPU_FTR_NOEXECUTE)
+#define CPU_FTRS_440x6 (CPU_FTR_NOEXECUTE | \
CPU_FTR_INDEXED_DCR)
#define CPU_FTRS_47X (CPU_FTRS_440x6)
#define CPU_FTRS_E200 (CPU_FTR_SPE_COMP | \
- CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
+ CPU_FTR_COHERENT_ICACHE | \
CPU_FTR_NOEXECUTE | \
CPU_FTR_DEBUG_LVL_EXC)
#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | \
- CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
+ CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_NOEXECUTE)
#define CPU_FTRS_E500_2 (CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | \
- CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
-#define CPU_FTRS_E500MC (CPU_FTR_NODSISRALIGN | \
+ CPU_FTR_NOEXECUTE)
+#define CPU_FTRS_E500MC ( \
CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
/*
* e5500/e6500 erratum A-006958 is a timebase bug that can use the
* same workaround as CPU_FTR_CELL_TB_BUG.
*/
-#define CPU_FTRS_E5500 (CPU_FTR_NODSISRALIGN | \
+#define CPU_FTRS_E5500 ( \
CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_CELL_TB_BUG)
-#define CPU_FTRS_E6500 (CPU_FTR_NODSISRALIGN | \
+#define CPU_FTRS_E6500 ( \
CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \
@@ -554,7 +553,6 @@ enum {
#define CPU_FTRS_DT_CPU_BASE \
(CPU_FTR_LWSYNC | \
CPU_FTR_FPU_UNAVAILABLE | \
- CPU_FTR_NODSISRALIGN | \
CPU_FTR_NOEXECUTE | \
CPU_FTR_COHERENT_ICACHE | \
CPU_FTR_STCX_CHECKS_ADDRESS | \
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 1098863e17ee..c598961d9f15 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -273,13 +273,6 @@ static int __init feat_enable_idle_nap(struct dt_cpu_feature *f)
return 1;
}
-static int __init feat_enable_align_dsisr(struct dt_cpu_feature *f)
-{
- cur_cpu_spec->cpu_features &= ~CPU_FTR_NODSISRALIGN;
-
- return 1;
-}
-
static int __init feat_enable_idle_stop(struct dt_cpu_feature *f)
{
u64 lpcr;
@@ -641,7 +634,6 @@ static struct dt_cpu_feature_match __initdata
{"tm-suspend-hypervisor-assist", feat_enable, CPU_FTR_P9_TM_HV_ASSIST},
{"tm-suspend-xer-so-bug", feat_enable, CPU_FTR_P9_TM_XER_SO_BUG},
{"idle-nap", feat_enable_idle_nap, 0},
- {"alignment-interrupt-dsisr", feat_enable_align_dsisr, 0},
{"idle-stop", feat_enable_idle_stop, 0},
{"machine-check-power8", feat_enable_mce_power8, 0},
{"performance-monitor-power8", feat_enable_pmu_power8, 0},
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index c1545f22c077..a5a5acb627fe 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -165,7 +165,7 @@ static struct ibm_pa_feature {
#ifdef CONFIG_PPC_RADIX_MMU
{ .pabyte = 40, .pabit = 0, .mmu_features = MMU_FTR_TYPE_RADIX | MMU_FTR_GTSE },
#endif
- { .pabyte = 1, .pabit = 1, .invert = 1, .cpu_features = CPU_FTR_NODSISRALIGN },
+ { .pabyte = 1, .pabit = 1, .invert = 1, },
{ .pabyte = 5, .pabit = 0, .cpu_features = CPU_FTR_REAL_LE,
.cpu_user_ftrs = PPC_FEATURE_TRUE_LE },
/*
--
2.25.0
^ 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