LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] powernv: powercap: Add hard minimum powercap
From: Shilpasri G Bhat @ 2019-03-01  6:25 UTC (permalink / raw)
  To: mpe; +Cc: ego, linuxppc-dev, linux-kernel, Shilpasri G Bhat, dja

In POWER9, OCC(On-Chip-Controller) provides for hard and soft system
powercapping range. The hard powercap range is guaranteed while soft
powercap may or may not be enforced by OCC due to various power-thermal
reasons based on system configuration and workloads. This patch adds
a sysfs file to export the hard minimum powercap limit to allow the
user to set the appropriate powercap value that can be managed by the
system.

Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
---
Changes from V1:
- s/asserted/enforced by OCC

 .../ABI/testing/sysfs-firmware-opal-powercap       | 10 ++++
 arch/powerpc/platforms/powernv/opal-powercap.c     | 66 +++++++++-------------
 2 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-powercap b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
index c9b66ec..e37d43e 100644
--- a/Documentation/ABI/testing/sysfs-firmware-opal-powercap
+++ b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
@@ -29,3 +29,13 @@ Description:	System powercap directory and attributes applicable for
 		  creates a request for setting a new-powercap. The
 		  powercap requested must be between powercap-min
 		  and powercap-max.
+
+What:		/sys/firmware/opal/powercap/system-powercap/powercap-hard-min
+Date:		March 2019
+Contact:	Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description:	Hard minimum powercap
+
+		This file provides the hard minimum powercap limit in Watts.
+		The powercap value above hard minimum limit is guaranteed to be
+		enforced by OCC and the powercap value below this limit may or
+		may not be guaranteed.
diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c
index d90ee4f..38408e7 100644
--- a/arch/powerpc/platforms/powernv/opal-powercap.c
+++ b/arch/powerpc/platforms/powernv/opal-powercap.c
@@ -139,10 +139,24 @@ static void powercap_add_attr(int handle, const char *name,
 	attr->handle = handle;
 	sysfs_attr_init(&attr->attr.attr);
 	attr->attr.attr.name = name;
-	attr->attr.attr.mode = 0444;
+
+	if (!strncmp(name, "powercap-current", strlen(name))) {
+		attr->attr.attr.mode = 0664;
+		attr->attr.store = powercap_store;
+	} else {
+		attr->attr.attr.mode = 0444;
+	}
+
 	attr->attr.show = powercap_show;
 }
 
+static const char * const powercap_strs[] = {
+	"powercap-max",
+	"powercap-min",
+	"powercap-current",
+	"powercap-hard-min",
+};
+
 void __init opal_powercap_init(void)
 {
 	struct device_node *powercap, *node;
@@ -167,60 +181,34 @@ void __init opal_powercap_init(void)
 
 	i = 0;
 	for_each_child_of_node(powercap, node) {
-		u32 cur, min, max;
-		int j = 0;
-		bool has_cur = false, has_min = false, has_max = false;
+		u32 id;
+		int j, count = 0;
 
-		if (!of_property_read_u32(node, "powercap-min", &min)) {
-			j++;
-			has_min = true;
-		}
-
-		if (!of_property_read_u32(node, "powercap-max", &max)) {
-			j++;
-			has_max = true;
-		}
+		for (j = 0; j < ARRAY_SIZE(powercap_strs); j++)
+			if (!of_property_read_u32(node, powercap_strs[j], &id))
+				count++;
 
-		if (!of_property_read_u32(node, "powercap-current", &cur)) {
-			j++;
-			has_cur = true;
-		}
-
-		pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr),
+		pcaps[i].pattrs = kcalloc(count, sizeof(struct powercap_attr),
 					  GFP_KERNEL);
 		if (!pcaps[i].pattrs)
 			goto out_pcaps_pattrs;
 
-		pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *),
+		pcaps[i].pg.attrs = kcalloc(count + 1,
+					    sizeof(struct attribute *),
 					    GFP_KERNEL);
 		if (!pcaps[i].pg.attrs) {
 			kfree(pcaps[i].pattrs);
 			goto out_pcaps_pattrs;
 		}
 
-		j = 0;
 		pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node);
-		if (has_min) {
-			powercap_add_attr(min, "powercap-min",
-					  &pcaps[i].pattrs[j]);
-			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
-			j++;
-		}
-
-		if (has_max) {
-			powercap_add_attr(max, "powercap-max",
-					  &pcaps[i].pattrs[j]);
-			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
-			j++;
-		}
+		for (j = 0; j < ARRAY_SIZE(powercap_strs); j++) {
+			if (of_property_read_u32(node, powercap_strs[j], &id))
+				continue;
 
-		if (has_cur) {
-			powercap_add_attr(cur, "powercap-current",
+			powercap_add_attr(id, powercap_strs[j],
 					  &pcaps[i].pattrs[j]);
-			pcaps[i].pattrs[j].attr.attr.mode |= 0220;
-			pcaps[i].pattrs[j].attr.store = powercap_store;
 			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
-			j++;
 		}
 
 		if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) {
-- 
1.8.3.1


^ permalink raw reply related

* Re: [alsa-devel] [PATCH] ASoC: cs42xx8: Remove S32_LE in format list
From: Matt Flax @ 2019-03-01  5:04 UTC (permalink / raw)
  To: Nicolin Chen, S.j. Wang
  Cc: alsa-devel@alsa-project.org, timur@kernel.org,
	Xiubo.Lee@gmail.com, festevam@gmail.com, broonie@kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20190301045041.GA5064@Asurada>

It would be a mistake to remove S32_LE from the format list.

If you removed that, then we wouldn't be able to do 32 bit native 
playback - it would force users to go through an ALSA plugin.

If you look at the cs42448 data sheet for example, the I2S and TDM bus 
uses a 32 bit word size. For that reason, native S32_LE format is 
handled by the codec. While the codec only uses the 24 MSBs, the I2S bus 
is 32 bit.

Matt

On 1/3/19 3:50 pm, Nicolin Chen wrote:
> Hi Shengjiu,
>
> On Thu, Feb 28, 2019 at 05:56:31AM +0000, S.j. Wang wrote:
>> cs42xx8 is a 24-bit A/D and 24-bit D/A device, so the S32_LE
>> should not be in the supported format list.
>>
>> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
>> ---
>>   sound/soc/codecs/cs42xx8.c | 3 +--
> This is for cs42xx8 codec driver, but its maintainers aren't
> seemly in To/Cc list. Please run ./scripts/get_maintainer.pl
> for it and resend.
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply

* Re: [PATCH] ASoC: cs42xx8: Remove S32_LE in format list
From: Nicolin Chen @ 2019-03-01  4:50 UTC (permalink / raw)
  To: S.j. Wang
  Cc: alsa-devel@alsa-project.org, timur@kernel.org,
	Xiubo.Lee@gmail.com, festevam@gmail.com, broonie@kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1551333389-22791-1-git-send-email-shengjiu.wang@nxp.com>

Hi Shengjiu,

On Thu, Feb 28, 2019 at 05:56:31AM +0000, S.j. Wang wrote:
> cs42xx8 is a 24-bit A/D and 24-bit D/A device, so the S32_LE
> should not be in the supported format list.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
>  sound/soc/codecs/cs42xx8.c | 3 +--

This is for cs42xx8 codec driver, but its maintainers aren't
seemly in To/Cc list. Please run ./scripts/get_maintainer.pl
for it and resend.

^ permalink raw reply

* ignore this Re: [PATCH kernel v2] KVM: PPC: Allocate guest TCEs on demand too
From: Alexey Kardashevskiy @ 2019-03-01  4:35 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190301043411.89935-1-aik@ozlabs.ru>

Ignore this as I forgot to change v2 to v3 so I reposted this.


On 01/03/2019 15:34, Alexey Kardashevskiy wrote:
> We already allocate hardware TCE tables in multiple levels and skip
> intermediate levels when we can, now it is a turn of the KVM TCE tables.
> Thankfully these are allocated already in 2 levels.
> 
> This moves the table's last level allocation from the creating helper to
> kvmppc_tce_put() and kvm_spapr_tce_fault().
> 
> This adds kvmppc_rm_ioba_validate() to do an additional test if
> the consequent kvmppc_tce_put() needs a page which has not been allocated;
> if this is the case, we bail out to virtual mode handlers.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> Changes:
> v3:
> * fixed alignments in kvmppc_rm_ioba_validate
> 
> v2:
> * added kvm mutex around alloc_page to prevent races; in both place we
> test the pointer, if NULL, then take a lock and check again so on a fast
> path we do not take a lock at all
> 
> 
> ---
> For NVLink2 passthrough guests with 128TiB DMA windows and very fragmented
> system RAM the difference is gigabytes of RAM.
> ---
>  arch/powerpc/kvm/book3s_64_vio.c    | 29 ++++++------
>  arch/powerpc/kvm/book3s_64_vio_hv.c | 71 ++++++++++++++++++++++++++---
>  2 files changed, 81 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index f02b04973710..7eed8c90ea3d 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -228,7 +228,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
>  	unsigned long i, npages = kvmppc_tce_pages(stt->size);
>  
>  	for (i = 0; i < npages; i++)
> -		__free_page(stt->pages[i]);
> +		if (stt->pages[i])
> +			__free_page(stt->pages[i]);
>  
>  	kfree(stt);
>  }
> @@ -242,6 +243,20 @@ static vm_fault_t kvm_spapr_tce_fault(struct vm_fault *vmf)
>  		return VM_FAULT_SIGBUS;
>  
>  	page = stt->pages[vmf->pgoff];
> +	if (!page) {
> +		mutex_lock(&stt->kvm->lock);
> +		page = stt->pages[vmf->pgoff];
> +		if (!page) {
> +			page  = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +			if (!page) {
> +				mutex_unlock(&stt->kvm->lock);
> +				return VM_FAULT_OOM;
> +			}
> +			stt->pages[vmf->pgoff] = page;
> +		}
> +		mutex_unlock(&stt->kvm->lock);
> +	}
> +
>  	get_page(page);
>  	vmf->page = page;
>  	return 0;
> @@ -296,7 +311,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	struct kvmppc_spapr_tce_table *siter;
>  	unsigned long npages, size = args->size;
>  	int ret = -ENOMEM;
> -	int i;
>  
>  	if (!args->size || args->page_shift < 12 || args->page_shift > 34 ||
>  		(args->offset + args->size > (ULLONG_MAX >> args->page_shift)))
> @@ -320,12 +334,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	stt->kvm = kvm;
>  	INIT_LIST_HEAD_RCU(&stt->iommu_tables);
>  
> -	for (i = 0; i < npages; i++) {
> -		stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
> -		if (!stt->pages[i])
> -			goto fail;
> -	}
> -
>  	mutex_lock(&kvm->lock);
>  
>  	/* Check this LIOBN hasn't been previously allocated */
> @@ -352,11 +360,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	if (ret >= 0)
>  		return ret;
>  
> - fail:
> -	for (i = 0; i < npages; i++)
> -		if (stt->pages[i])
> -			__free_page(stt->pages[i]);
> -
>  	kfree(stt);
>   fail_acct:
>  	kvmppc_account_memlimit(kvmppc_stt_pages(npages), false);
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 2206bc729b9a..1cd9373f8bdc 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -158,23 +158,78 @@ static u64 *kvmppc_page_address(struct page *page)
>  	return (u64 *) page_address(page);
>  }
>  
> +/*
> + * TCEs pages are allocated in kvmppc_tce_put() which won't be able to do so
> + * in real mode.
> + * Check if kvmppc_tce_put() can succeed in real mode, i.e. a TCEs page is
> + * allocated or not required (when clearing a tce entry).
> + */
> +static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
> +		unsigned long ioba, unsigned long npages, bool clearing)
> +{
> +	unsigned long i, idx, sttpage, sttpages;
> +	unsigned long ret = kvmppc_ioba_validate(stt, ioba, npages);
> +
> +	if (ret)
> +		return ret;
> +	/*
> +	 * clearing==true says kvmppc_tce_put won't be allocating pages
> +	 * for empty tces.
> +	 */
> +	if (clearing)
> +		return H_SUCCESS;
> +
> +	idx = (ioba >> stt->page_shift) - stt->offset;
> +	sttpage = idx / TCES_PER_PAGE;
> +	sttpages = _ALIGN_UP(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
> +			TCES_PER_PAGE;
> +	for (i = sttpage; i < sttpage + sttpages; ++i)
> +		if (!stt->pages[i])
> +			return H_TOO_HARD;
> +
> +	return H_SUCCESS;
> +}
> +
>  /*
>   * Handles TCE requests for emulated devices.
>   * Puts guest TCE values to the table and expects user space to convert them.
>   * Called in both real and virtual modes.
>   * Cannot fail so kvmppc_tce_validate must be called before it.
>   *
> - * WARNING: This will be called in real-mode on HV KVM and virtual
> - *          mode on PR KVM
> + * WARNING: This will be called in real-mode on HV HPT KVM and virtual
> + *          mode on PR KVM or HV radix KVM
>   */
>  void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
>  		unsigned long idx, unsigned long tce)
>  {
>  	struct page *page;
>  	u64 *tbl;
> +	unsigned long sttpage;
>  
>  	idx -= stt->offset;
> -	page = stt->pages[idx / TCES_PER_PAGE];
> +	sttpage = idx / TCES_PER_PAGE;
> +	page = stt->pages[sttpage];
> +
> +	if (!page) {
> +		/* We allow any TCE, not just with read|write permissions */
> +		if (!tce)
> +			return;
> +		/*
> +		 * We must not end up here in real mode,
> +		 * kvmppc_rm_ioba_validate() takes care of this.
> +		 */
> +		mutex_lock(&stt->kvm->lock);
> +		page = stt->pages[sttpage];
> +		if (!page) {
> +			page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +			if (WARN_ON_ONCE(!page)) {
> +				mutex_unlock(&stt->kvm->lock);
> +				return;
> +			}
> +			stt->pages[sttpage] = page;
> +		}
> +		mutex_unlock(&stt->kvm->lock);
> +	}
>  	tbl = kvmppc_page_address(page);
>  
>  	tbl[idx % TCES_PER_PAGE] = tce;
> @@ -381,7 +436,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	if (!stt)
>  		return H_TOO_HARD;
>  
> -	ret = kvmppc_ioba_validate(stt, ioba, 1);
> +	ret = kvmppc_rm_ioba_validate(stt, ioba, 1, tce == 0);
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> @@ -480,7 +535,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
>  	if (tce_list & (SZ_4K - 1))
>  		return H_PARAMETER;
>  
> -	ret = kvmppc_ioba_validate(stt, ioba, npages);
> +	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, false);
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> @@ -583,7 +638,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
>  	if (!stt)
>  		return H_TOO_HARD;
>  
> -	ret = kvmppc_ioba_validate(stt, ioba, npages);
> +	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, tce_value == 0);
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> @@ -635,6 +690,10 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  
>  	idx = (ioba >> stt->page_shift) - stt->offset;
>  	page = stt->pages[idx / TCES_PER_PAGE];
> +	if (!page) {
> +		vcpu->arch.regs.gpr[4] = 0;
> +		return H_SUCCESS;
> +	}
>  	tbl = (u64 *)page_address(page);
>  
>  	vcpu->arch.regs.gpr[4] = tbl[idx % TCES_PER_PAGE];
> 

-- 
Alexey

^ permalink raw reply

* [PATCH kernel v3] KVM: PPC: Allocate guest TCEs on demand too
From: Alexey Kardashevskiy @ 2019-03-01  4:34 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Alexey Kardashevskiy, kvm-ppc, David Gibson

We already allocate hardware TCE tables in multiple levels and skip
intermediate levels when we can, now it is a turn of the KVM TCE tables.
Thankfully these are allocated already in 2 levels.

This moves the table's last level allocation from the creating helper to
kvmppc_tce_put() and kvm_spapr_tce_fault().

This adds kvmppc_rm_ioba_validate() to do an additional test if
the consequent kvmppc_tce_put() needs a page which has not been allocated;
if this is the case, we bail out to virtual mode handlers.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v3:
* fixed alignments in kvmppc_rm_ioba_validate

v2:
* added kvm mutex around alloc_page to prevent races; in both place we
test the pointer, if NULL, then take a lock and check again so on a fast
path we do not take a lock at all


---
For NVLink2 passthrough guests with 128TiB DMA windows and very fragmented
system RAM the difference is gigabytes of RAM.
---
 arch/powerpc/kvm/book3s_64_vio.c    | 29 ++++++------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 71 ++++++++++++++++++++++++++---
 2 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index f02b04973710..7eed8c90ea3d 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -228,7 +228,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
 	unsigned long i, npages = kvmppc_tce_pages(stt->size);
 
 	for (i = 0; i < npages; i++)
-		__free_page(stt->pages[i]);
+		if (stt->pages[i])
+			__free_page(stt->pages[i]);
 
 	kfree(stt);
 }
@@ -242,6 +243,20 @@ static vm_fault_t kvm_spapr_tce_fault(struct vm_fault *vmf)
 		return VM_FAULT_SIGBUS;
 
 	page = stt->pages[vmf->pgoff];
+	if (!page) {
+		mutex_lock(&stt->kvm->lock);
+		page = stt->pages[vmf->pgoff];
+		if (!page) {
+			page  = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (!page) {
+				mutex_unlock(&stt->kvm->lock);
+				return VM_FAULT_OOM;
+			}
+			stt->pages[vmf->pgoff] = page;
+		}
+		mutex_unlock(&stt->kvm->lock);
+	}
+
 	get_page(page);
 	vmf->page = page;
 	return 0;
@@ -296,7 +311,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	struct kvmppc_spapr_tce_table *siter;
 	unsigned long npages, size = args->size;
 	int ret = -ENOMEM;
-	int i;
 
 	if (!args->size || args->page_shift < 12 || args->page_shift > 34 ||
 		(args->offset + args->size > (ULLONG_MAX >> args->page_shift)))
@@ -320,12 +334,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	stt->kvm = kvm;
 	INIT_LIST_HEAD_RCU(&stt->iommu_tables);
 
-	for (i = 0; i < npages; i++) {
-		stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
-		if (!stt->pages[i])
-			goto fail;
-	}
-
 	mutex_lock(&kvm->lock);
 
 	/* Check this LIOBN hasn't been previously allocated */
@@ -352,11 +360,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	if (ret >= 0)
 		return ret;
 
- fail:
-	for (i = 0; i < npages; i++)
-		if (stt->pages[i])
-			__free_page(stt->pages[i]);
-
 	kfree(stt);
  fail_acct:
 	kvmppc_account_memlimit(kvmppc_stt_pages(npages), false);
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 2206bc729b9a..1cd9373f8bdc 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -158,23 +158,78 @@ static u64 *kvmppc_page_address(struct page *page)
 	return (u64 *) page_address(page);
 }
 
+/*
+ * TCEs pages are allocated in kvmppc_tce_put() which won't be able to do so
+ * in real mode.
+ * Check if kvmppc_tce_put() can succeed in real mode, i.e. a TCEs page is
+ * allocated or not required (when clearing a tce entry).
+ */
+static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
+		unsigned long ioba, unsigned long npages, bool clearing)
+{
+	unsigned long i, idx, sttpage, sttpages;
+	unsigned long ret = kvmppc_ioba_validate(stt, ioba, npages);
+
+	if (ret)
+		return ret;
+	/*
+	 * clearing==true says kvmppc_tce_put won't be allocating pages
+	 * for empty tces.
+	 */
+	if (clearing)
+		return H_SUCCESS;
+
+	idx = (ioba >> stt->page_shift) - stt->offset;
+	sttpage = idx / TCES_PER_PAGE;
+	sttpages = _ALIGN_UP(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
+			TCES_PER_PAGE;
+	for (i = sttpage; i < sttpage + sttpages; ++i)
+		if (!stt->pages[i])
+			return H_TOO_HARD;
+
+	return H_SUCCESS;
+}
+
 /*
  * Handles TCE requests for emulated devices.
  * Puts guest TCE values to the table and expects user space to convert them.
  * Called in both real and virtual modes.
  * Cannot fail so kvmppc_tce_validate must be called before it.
  *
- * WARNING: This will be called in real-mode on HV KVM and virtual
- *          mode on PR KVM
+ * WARNING: This will be called in real-mode on HV HPT KVM and virtual
+ *          mode on PR KVM or HV radix KVM
  */
 void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
 		unsigned long idx, unsigned long tce)
 {
 	struct page *page;
 	u64 *tbl;
+	unsigned long sttpage;
 
 	idx -= stt->offset;
-	page = stt->pages[idx / TCES_PER_PAGE];
+	sttpage = idx / TCES_PER_PAGE;
+	page = stt->pages[sttpage];
+
+	if (!page) {
+		/* We allow any TCE, not just with read|write permissions */
+		if (!tce)
+			return;
+		/*
+		 * We must not end up here in real mode,
+		 * kvmppc_rm_ioba_validate() takes care of this.
+		 */
+		mutex_lock(&stt->kvm->lock);
+		page = stt->pages[sttpage];
+		if (!page) {
+			page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (WARN_ON_ONCE(!page)) {
+				mutex_unlock(&stt->kvm->lock);
+				return;
+			}
+			stt->pages[sttpage] = page;
+		}
+		mutex_unlock(&stt->kvm->lock);
+	}
 	tbl = kvmppc_page_address(page);
 
 	tbl[idx % TCES_PER_PAGE] = tce;
@@ -381,7 +436,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (!stt)
 		return H_TOO_HARD;
 
-	ret = kvmppc_ioba_validate(stt, ioba, 1);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, 1, tce == 0);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -480,7 +535,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 	if (tce_list & (SZ_4K - 1))
 		return H_PARAMETER;
 
-	ret = kvmppc_ioba_validate(stt, ioba, npages);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, false);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -583,7 +638,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
 	if (!stt)
 		return H_TOO_HARD;
 
-	ret = kvmppc_ioba_validate(stt, ioba, npages);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, tce_value == 0);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -635,6 +690,10 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 
 	idx = (ioba >> stt->page_shift) - stt->offset;
 	page = stt->pages[idx / TCES_PER_PAGE];
+	if (!page) {
+		vcpu->arch.regs.gpr[4] = 0;
+		return H_SUCCESS;
+	}
 	tbl = (u64 *)page_address(page);
 
 	vcpu->arch.regs.gpr[4] = tbl[idx % TCES_PER_PAGE];
-- 
2.17.1


^ permalink raw reply related

* [PATCH kernel v2] KVM: PPC: Allocate guest TCEs on demand too
From: Alexey Kardashevskiy @ 2019-03-01  4:34 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Alexey Kardashevskiy, kvm-ppc, David Gibson

We already allocate hardware TCE tables in multiple levels and skip
intermediate levels when we can, now it is a turn of the KVM TCE tables.
Thankfully these are allocated already in 2 levels.

This moves the table's last level allocation from the creating helper to
kvmppc_tce_put() and kvm_spapr_tce_fault().

This adds kvmppc_rm_ioba_validate() to do an additional test if
the consequent kvmppc_tce_put() needs a page which has not been allocated;
if this is the case, we bail out to virtual mode handlers.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v3:
* fixed alignments in kvmppc_rm_ioba_validate

v2:
* added kvm mutex around alloc_page to prevent races; in both place we
test the pointer, if NULL, then take a lock and check again so on a fast
path we do not take a lock at all


---
For NVLink2 passthrough guests with 128TiB DMA windows and very fragmented
system RAM the difference is gigabytes of RAM.
---
 arch/powerpc/kvm/book3s_64_vio.c    | 29 ++++++------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 71 ++++++++++++++++++++++++++---
 2 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index f02b04973710..7eed8c90ea3d 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -228,7 +228,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
 	unsigned long i, npages = kvmppc_tce_pages(stt->size);
 
 	for (i = 0; i < npages; i++)
-		__free_page(stt->pages[i]);
+		if (stt->pages[i])
+			__free_page(stt->pages[i]);
 
 	kfree(stt);
 }
@@ -242,6 +243,20 @@ static vm_fault_t kvm_spapr_tce_fault(struct vm_fault *vmf)
 		return VM_FAULT_SIGBUS;
 
 	page = stt->pages[vmf->pgoff];
+	if (!page) {
+		mutex_lock(&stt->kvm->lock);
+		page = stt->pages[vmf->pgoff];
+		if (!page) {
+			page  = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (!page) {
+				mutex_unlock(&stt->kvm->lock);
+				return VM_FAULT_OOM;
+			}
+			stt->pages[vmf->pgoff] = page;
+		}
+		mutex_unlock(&stt->kvm->lock);
+	}
+
 	get_page(page);
 	vmf->page = page;
 	return 0;
@@ -296,7 +311,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	struct kvmppc_spapr_tce_table *siter;
 	unsigned long npages, size = args->size;
 	int ret = -ENOMEM;
-	int i;
 
 	if (!args->size || args->page_shift < 12 || args->page_shift > 34 ||
 		(args->offset + args->size > (ULLONG_MAX >> args->page_shift)))
@@ -320,12 +334,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	stt->kvm = kvm;
 	INIT_LIST_HEAD_RCU(&stt->iommu_tables);
 
-	for (i = 0; i < npages; i++) {
-		stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
-		if (!stt->pages[i])
-			goto fail;
-	}
-
 	mutex_lock(&kvm->lock);
 
 	/* Check this LIOBN hasn't been previously allocated */
@@ -352,11 +360,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	if (ret >= 0)
 		return ret;
 
- fail:
-	for (i = 0; i < npages; i++)
-		if (stt->pages[i])
-			__free_page(stt->pages[i]);
-
 	kfree(stt);
  fail_acct:
 	kvmppc_account_memlimit(kvmppc_stt_pages(npages), false);
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 2206bc729b9a..1cd9373f8bdc 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -158,23 +158,78 @@ static u64 *kvmppc_page_address(struct page *page)
 	return (u64 *) page_address(page);
 }
 
+/*
+ * TCEs pages are allocated in kvmppc_tce_put() which won't be able to do so
+ * in real mode.
+ * Check if kvmppc_tce_put() can succeed in real mode, i.e. a TCEs page is
+ * allocated or not required (when clearing a tce entry).
+ */
+static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
+		unsigned long ioba, unsigned long npages, bool clearing)
+{
+	unsigned long i, idx, sttpage, sttpages;
+	unsigned long ret = kvmppc_ioba_validate(stt, ioba, npages);
+
+	if (ret)
+		return ret;
+	/*
+	 * clearing==true says kvmppc_tce_put won't be allocating pages
+	 * for empty tces.
+	 */
+	if (clearing)
+		return H_SUCCESS;
+
+	idx = (ioba >> stt->page_shift) - stt->offset;
+	sttpage = idx / TCES_PER_PAGE;
+	sttpages = _ALIGN_UP(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
+			TCES_PER_PAGE;
+	for (i = sttpage; i < sttpage + sttpages; ++i)
+		if (!stt->pages[i])
+			return H_TOO_HARD;
+
+	return H_SUCCESS;
+}
+
 /*
  * Handles TCE requests for emulated devices.
  * Puts guest TCE values to the table and expects user space to convert them.
  * Called in both real and virtual modes.
  * Cannot fail so kvmppc_tce_validate must be called before it.
  *
- * WARNING: This will be called in real-mode on HV KVM and virtual
- *          mode on PR KVM
+ * WARNING: This will be called in real-mode on HV HPT KVM and virtual
+ *          mode on PR KVM or HV radix KVM
  */
 void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
 		unsigned long idx, unsigned long tce)
 {
 	struct page *page;
 	u64 *tbl;
+	unsigned long sttpage;
 
 	idx -= stt->offset;
-	page = stt->pages[idx / TCES_PER_PAGE];
+	sttpage = idx / TCES_PER_PAGE;
+	page = stt->pages[sttpage];
+
+	if (!page) {
+		/* We allow any TCE, not just with read|write permissions */
+		if (!tce)
+			return;
+		/*
+		 * We must not end up here in real mode,
+		 * kvmppc_rm_ioba_validate() takes care of this.
+		 */
+		mutex_lock(&stt->kvm->lock);
+		page = stt->pages[sttpage];
+		if (!page) {
+			page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (WARN_ON_ONCE(!page)) {
+				mutex_unlock(&stt->kvm->lock);
+				return;
+			}
+			stt->pages[sttpage] = page;
+		}
+		mutex_unlock(&stt->kvm->lock);
+	}
 	tbl = kvmppc_page_address(page);
 
 	tbl[idx % TCES_PER_PAGE] = tce;
@@ -381,7 +436,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (!stt)
 		return H_TOO_HARD;
 
-	ret = kvmppc_ioba_validate(stt, ioba, 1);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, 1, tce == 0);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -480,7 +535,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 	if (tce_list & (SZ_4K - 1))
 		return H_PARAMETER;
 
-	ret = kvmppc_ioba_validate(stt, ioba, npages);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, false);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -583,7 +638,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
 	if (!stt)
 		return H_TOO_HARD;
 
-	ret = kvmppc_ioba_validate(stt, ioba, npages);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, tce_value == 0);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -635,6 +690,10 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 
 	idx = (ioba >> stt->page_shift) - stt->offset;
 	page = stt->pages[idx / TCES_PER_PAGE];
+	if (!page) {
+		vcpu->arch.regs.gpr[4] = 0;
+		return H_SUCCESS;
+	}
 	tbl = (u64 *)page_address(page);
 
 	vcpu->arch.regs.gpr[4] = tbl[idx % TCES_PER_PAGE];
-- 
2.17.1


^ permalink raw reply related

* RE: [PATCH] ASoC: cs42xx8: Remove S32_LE in format list
From: S.j. Wang @ 2019-03-01  3:45 UTC (permalink / raw)
  To: Timur Tabi, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com,
	festevam@gmail.com, broonie@kernel.org,
	alsa-devel@alsa-project.org
  Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <ab0a0d6c-4905-328c-0e22-931c045ed8d9@kernel.org>

Hi

> > cs42xx8 is a 24-bit A/D and 24-bit D/A device, so the S32_LE should
> > not be in the supported format list.
> >
> > Signed-off-by: Shengjiu Wang<shengjiu.wang@nxp.com>
> 
> Is the device capable of accepting 32-bit samples, even if it downgrades it to
> 24-bit internally?  If so, then maybe SNDRV_PCM_FMTBIT_S32_LE should
> stay.
Yes,  the S32_LE can be accepted by device, it seems like that the device only
Use the upper 24bit, so the S32_LE result is same as S24_LE,  do you think the
S32_LE should be remained?

Best regards
Wang shengjiu



^ permalink raw reply

* [PATCH] KVM: PPC: powerpc: Add count cache flush parameters to kvmppc_get_cpu_char()
From: Suraj Jitindar Singh @ 2019-03-01  3:25 UTC (permalink / raw)
  To: kvm-ppc; +Cc: paulus, linuxppc-dev, kvm, Suraj Jitindar Singh

Add KVM_PPC_CPU_CHAR_BCCTR_FLUSH_ASSIST &
KVM_PPC_CPU_BEHAV_FLUSH_COUNT_CACHE to the characteristics returned from
the H_GET_CPU_CHARACTERISTICS H-CALL, as queried from either the
hypervisor or the device tree.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 arch/powerpc/include/uapi/asm/kvm.h |  2 ++
 arch/powerpc/kvm/powerpc.c          | 18 ++++++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 8c876c166ef2..26ca425f4c2c 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -463,10 +463,12 @@ struct kvm_ppc_cpu_char {
 #define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED	(1ULL << 58)
 #define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF	(1ULL << 57)
 #define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS	(1ULL << 56)
+#define KVM_PPC_CPU_CHAR_BCCTR_FLUSH_ASSIST	(1ull << 54)
 
 #define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY	(1ULL << 63)
 #define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR		(1ULL << 62)
 #define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR	(1ULL << 61)
+#define KVM_PPC_CPU_BEHAV_FLUSH_COUNT_CACHE	(1ull << 58)
 
 /* Per-vcpu XICS interrupt controller state */
 #define KVM_REG_PPC_ICP_STATE	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index b90a7d154180..a99dcac91e50 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -2189,10 +2189,12 @@ static int pseries_get_cpu_char(struct kvm_ppc_cpu_char *cp)
 			KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV |
 			KVM_PPC_CPU_CHAR_BR_HINT_HONOURED |
 			KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF |
-			KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;
+			KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS |
+			KVM_PPC_CPU_CHAR_BCCTR_FLUSH_ASSIST;
 		cp->behaviour_mask = KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY |
 			KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR |
-			KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
+			KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR |
+			KVM_PPC_CPU_BEHAV_FLUSH_COUNT_CACHE;
 	}
 	return 0;
 }
@@ -2251,12 +2253,16 @@ static int kvmppc_get_cpu_char(struct kvm_ppc_cpu_char *cp)
 		if (have_fw_feat(fw_features, "enabled",
 				 "fw-count-cache-disabled"))
 			cp->character |= KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;
+		if (have_fw_feat(fw_features, "enabled",
+				 "fw-count-cache-flush-bcctr2,0,0"))
+			cp->character |= KVM_PPC_CPU_CHAR_BCCTR_FLUSH_ASSIST;
 		cp->character_mask = KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 |
 			KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED |
 			KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 |
 			KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 |
 			KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV |
-			KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS;
+			KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS |
+			KVM_PPC_CPU_CHAR_BCCTR_FLUSH_ASSIST;
 
 		if (have_fw_feat(fw_features, "enabled",
 				 "speculation-policy-favor-security"))
@@ -2267,9 +2273,13 @@ static int kvmppc_get_cpu_char(struct kvm_ppc_cpu_char *cp)
 		if (!have_fw_feat(fw_features, "disabled",
 				  "needs-spec-barrier-for-bound-checks"))
 			cp->behaviour |= KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
+		if (have_fw_feat(fw_features, "enabled",
+				 "needs-count-cache-flush-on-context-switch"))
+			cp->behaviour |= KVM_PPC_CPU_BEHAV_FLUSH_COUNT_CACHE;
 		cp->behaviour_mask = KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY |
 			KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR |
-			KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
+			KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR |
+			KVM_PPC_CPU_BEHAV_FLUSH_COUNT_CACHE;
 
 		of_node_put(fw_features);
 	}
-- 
2.13.6


^ permalink raw reply related

* Re: [PATCH] powerpc: fix "sz" set but not used
From: Michael Ellerman @ 2019-03-01  3:24 UTC (permalink / raw)
  To: Qian Cai, benh, paulus; +Cc: Qian Cai, linuxppc-dev, linux-kernel
In-Reply-To: <20190228023505.80092-1-cai@lca.pw>

Qian Cai <cai@lca.pw> writes:
> arch/powerpc/mm/hugetlbpage-hash64.c: In function '__hash_page_huge':
> arch/powerpc/mm/hugetlbpage-hash64.c:29:28: warning: variable 'sz' set
> but not used [-Wunused-but-set-variable]

It's always nice to know *why* it's not used.

It's unlikely, but not impossible, that it's a bug that the variable is
not used.

To find out why:

  $ git log --oneline -S sz arch/powerpc/mm/hugetlbpage-hash64.c
  0895ecda7942 powerpc/mm: Bring hugepage PTE accessor functions back into sync with normal accessors
  883a3e523672 powerpc/mm: Split hash MMU specific hugepage code into a new file

Then we look at those, and see the the first one did:

@@ -89,8 +62,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
        if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
                /* No CPU has hugepages but lacks no execute, so we
                 * don't need to worry about that case */
-               rflags = hash_huge_page_do_lazy_icache(rflags, __pte(old_pte),
-                                                      trap, sz);
+               rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);


And if you read the commit log it's pretty clear the change was
deliberate and so sz should indeed be removed.

I've applied this as-is, no need to send a v2.

cheers

> diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
> index 2e6a8f9345d3..f6b09edc5e6e 100644
> --- a/arch/powerpc/mm/hugetlbpage-hash64.c
> +++ b/arch/powerpc/mm/hugetlbpage-hash64.c
> @@ -26,7 +26,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
>  	real_pte_t rpte;
>  	unsigned long vpn;
>  	unsigned long old_pte, new_pte;
> -	unsigned long rflags, pa, sz;
> +	unsigned long rflags, pa;
>  	long slot, offset;
>  
>  	BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
> @@ -73,7 +73,6 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
>  		offset = PTRS_PER_PMD;
>  	rpte = __real_pte(__pte(old_pte), ptep, offset);
>  
> -	sz = ((1UL) << shift);
>  	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
>  		/* No CPU has hugepages but lacks no execute, so we
>  		 * don't need to worry about that case */
> -- 
> 2.17.2 (Apple Git-113)

^ permalink raw reply

* Re: [PATCH 5/5] ocxl: Remove some unused exported symbols
From: Andrew Donnellan @ 2019-02-28  5:23 UTC (permalink / raw)
  To: Alastair D'Silva, alastair
  Cc: Frederic Barrat, Greg Kroah-Hartman, linuxppc-dev, linux-kernel,
	Arnd Bergmann
In-Reply-To: <20190227045741.21412-6-alastair@au1.ibm.com>

On 27/2/19 3:57 pm, Alastair D'Silva wrote:
> From: Alastair D'Silva <alastair@d-silva.org>
> 
> Remove some unused exported symbols.
> 
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org> > ---
>   drivers/misc/ocxl/config.c        |  2 --
>   drivers/misc/ocxl/ocxl_internal.h | 26 +++++++++++++++++++++++++-
>   include/misc/ocxl.h               | 23 -----------------------
>   3 files changed, 25 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
> index 026ac2ac4f9c..c90c2e4875bf 100644
> --- a/drivers/misc/ocxl/config.c
> +++ b/drivers/misc/ocxl/config.c
> @@ -299,7 +299,6 @@ int ocxl_config_check_afu_index(struct pci_dev *dev,
>   	}
>   	return 1;
>   }
> -EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index);
>   
>   static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn,
>   			struct ocxl_afu_config *afu)
> @@ -535,7 +534,6 @@ int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count)
>   {
>   	return pnv_ocxl_get_pasid_count(dev, count);
>   }
> -EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info);
>   
>   void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base,
>   			u32 pasid_count_log)
> diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h
> index 321b29e77f45..cd5a1e3cc950 100644
> --- a/drivers/misc/ocxl/ocxl_internal.h
> +++ b/drivers/misc/ocxl/ocxl_internal.h
> @@ -107,10 +107,34 @@ void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
>   int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
>   void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
>   
> +/*
> + * Get the max PASID value that can be used by the function
> + */
> +int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> +
> +int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> +
> +/*
> + * Check if an AFU index is valid for the given function.
> + *
> + * AFU indexes can be sparse, so a driver should check all indexes up
> + * to the maximum found in the function description
> + */
> +int ocxl_config_check_afu_index(struct pci_dev *dev,
> +				struct ocxl_fn_config *fn, int afu_idx);
> +
> +/**
> + * Update values within a Process Element
> + *
> + * link_handle: the link handle associated with the process element
> + * pasid: the PASID for the AFU context
> + * tid: the new thread id for the process element
> + */
> +int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
> +

This isn't actually exported, so if you spin a v2 do that separately 
from this patch or document the change.

Otherwise

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>

>   struct ocxl_context *ocxl_context_alloc(void);
>   int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
>   			struct address_space *mapping);
> -int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
>   int ocxl_context_mmap(struct ocxl_context *ctx,
>   			struct vm_area_struct *vma);
>   int ocxl_context_detach(struct ocxl_context *ctx);
> diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h
> index 4544573cc93c..9530d3be1b30 100644
> --- a/include/misc/ocxl.h
> +++ b/include/misc/ocxl.h
> @@ -56,15 +56,6 @@ struct ocxl_fn_config {
>   int ocxl_config_read_function(struct pci_dev *dev,
>   				struct ocxl_fn_config *fn);
>   
> -/*
> - * Check if an AFU index is valid for the given function.
> - *
> - * AFU indexes can be sparse, so a driver should check all indexes up
> - * to the maximum found in the function description
> - */
> -int ocxl_config_check_afu_index(struct pci_dev *dev,
> -				struct ocxl_fn_config *fn, int afu_idx);
> -
>   /*
>    * Read the configuration space of a function for the AFU specified by
>    * the index 'afu_idx'. Fills in a ocxl_afu_config structure
> @@ -74,11 +65,6 @@ int ocxl_config_read_afu(struct pci_dev *dev,
>   				struct ocxl_afu_config *afu,
>   				u8 afu_idx);
>   
> -/*
> - * Get the max PASID value that can be used by the function
> - */
> -int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> -
>   /*
>    * Tell an AFU, by writing in the configuration space, the PASIDs that
>    * it can use. Range starts at 'pasid_base' and its size is a multiple
> @@ -188,15 +174,6 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
>   		void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
>   		void *xsl_err_data);
>   
> -/**
> - * Update values within a Process Element
> - *
> - * link_handle: the link handle associated with the process element
> - * pasid: the PASID for the AFU context
> - * tid: the new thread id for the process element
> - */
> -int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
> -
>   /*
>    * Remove a Process Element from the Shared Process Area for a link
>    */
> 

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited


^ permalink raw reply

* Re: [PATCH kernel v2] KVM: PPC: Allocate guest TCEs on demand too
From: Alexey Kardashevskiy @ 2019-03-01  3:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190301013827.30504-1-aik@ozlabs.ru>



On 01/03/2019 12:38, Alexey Kardashevskiy wrote:
> We already allocate hardware TCE tables in multiple levels and skip
> intermediate levels when we can, now it is a turn of the KVM TCE tables.
> Thankfully these are allocated already in 2 levels.
> 
> This moves the table's last level allocation from the creating helper to
> kvmppc_tce_put() and kvm_spapr_tce_fault().
> 
> This adds kvmppc_rm_ioba_validate() to do an additional test if
> the consequent kvmppc_tce_put() needs a page which has not been allocated;
> if this is the case, we bail out to virtual mode handlers.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> Changes:
> v2:
> * added kvm mutex around alloc_page to prevent races; in both place we
> test the pointer, if NULL, then take a lock and check again so on a fast
> path we do not take a lock at all
> 
> 
> ---
> For NVLink2 passthrough guests with 128TiB DMA windows and very fragmented
> system RAM the difference is gigabytes of RAM.
> ---
>  arch/powerpc/kvm/book3s_64_vio.c    | 29 ++++++------
>  arch/powerpc/kvm/book3s_64_vio_hv.c | 69 ++++++++++++++++++++++++++---
>  2 files changed, 79 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index f02b049..7eed8c9 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -228,7 +228,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
>  	unsigned long i, npages = kvmppc_tce_pages(stt->size);
>  
>  	for (i = 0; i < npages; i++)
> -		__free_page(stt->pages[i]);
> +		if (stt->pages[i])
> +			__free_page(stt->pages[i]);
>  
>  	kfree(stt);
>  }
> @@ -242,6 +243,20 @@ static vm_fault_t kvm_spapr_tce_fault(struct vm_fault *vmf)
>  		return VM_FAULT_SIGBUS;
>  
>  	page = stt->pages[vmf->pgoff];
> +	if (!page) {
> +		mutex_lock(&stt->kvm->lock);
> +		page = stt->pages[vmf->pgoff];
> +		if (!page) {
> +			page  = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +			if (!page) {
> +				mutex_unlock(&stt->kvm->lock);
> +				return VM_FAULT_OOM;
> +			}
> +			stt->pages[vmf->pgoff] = page;
> +		}
> +		mutex_unlock(&stt->kvm->lock);
> +	}
> +
>  	get_page(page);
>  	vmf->page = page;
>  	return 0;
> @@ -296,7 +311,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	struct kvmppc_spapr_tce_table *siter;
>  	unsigned long npages, size = args->size;
>  	int ret = -ENOMEM;
> -	int i;
>  
>  	if (!args->size || args->page_shift < 12 || args->page_shift > 34 ||
>  		(args->offset + args->size > (ULLONG_MAX >> args->page_shift)))
> @@ -320,12 +334,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	stt->kvm = kvm;
>  	INIT_LIST_HEAD_RCU(&stt->iommu_tables);
>  
> -	for (i = 0; i < npages; i++) {
> -		stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
> -		if (!stt->pages[i])
> -			goto fail;
> -	}
> -
>  	mutex_lock(&kvm->lock);
>  
>  	/* Check this LIOBN hasn't been previously allocated */
> @@ -352,11 +360,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	if (ret >= 0)
>  		return ret;
>  
> - fail:
> -	for (i = 0; i < npages; i++)
> -		if (stt->pages[i])
> -			__free_page(stt->pages[i]);
> -
>  	kfree(stt);
>   fail_acct:
>  	kvmppc_account_memlimit(kvmppc_stt_pages(npages), false);
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 2206bc7..a0912d5 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -158,23 +158,76 @@ static u64 *kvmppc_page_address(struct page *page)
>  	return (u64 *) page_address(page);
>  }
>  
> +/*
> + * TCEs pages are allocated in kvmppc_tce_put() which won't be able to do so
> + * in real mode.
> + * Check if kvmppc_tce_put() can succeed in real mode, i.e. a TCEs page is
> + * allocated or not required (when clearing a tce entry).
> + */
> +static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
> +		unsigned long ioba, unsigned long npages, bool clearing)
> +{
> +	unsigned long i, sttpage, sttpages;
> +	unsigned long ret = kvmppc_ioba_validate(stt, ioba, npages);
> +
> +	if (ret)
> +		return ret;
> +	/*
> +	 * clearing==true says kvmppc_tce_put won't be allocating pages
> +	 * for empty tces.
> +	 */
> +	if (clearing)
> +		return H_SUCCESS;
> +
> +	sttpage = ((ioba >> stt->page_shift) - stt->offset) / TCES_PER_PAGE;
> +	sttpages = (npages + TCES_PER_PAGE - 1) / TCES_PER_PAGE;


This is wrong, v3 is coming.


-- 
Alexey

^ permalink raw reply

* Re: [PATCH] ASoC: fsl_asrc: add protection for the asrc of older version
From: Nicolin Chen @ 2019-03-01  2:53 UTC (permalink / raw)
  To: S.j. Wang
  Cc: alsa-devel@alsa-project.org, timur@kernel.org,
	Xiubo.Lee@gmail.com, festevam@gmail.com, broonie@kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1551407560-29950-1-git-send-email-shengjiu.wang@nxp.com>

Hi Shengjiu,

On Fri, Mar 01, 2019 at 02:32:38AM +0000, S.j. Wang wrote:
> There is a constraint for the channel number setting on the
> asrc of older version (e.g. imx35), the channel number should
> be even, odd number isn't valid.
> 
> So add protection when the asrc of older version is used.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
>  sound/soc/fsl/fsl_asrc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> index 528e8b108422..b3b3c5e15ef1 100644
> --- a/sound/soc/fsl/fsl_asrc.c
> +++ b/sound/soc/fsl/fsl_asrc.c
> @@ -109,7 +109,8 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
>  	if (index == ASRC_INVALID_PAIR) {
>  		dev_err(dev, "all pairs are busy now\n");
>  		ret = -EBUSY;
> -	} else if (asrc_priv->channel_avail < channels) {
> +	} else if (asrc_priv->channel_avail < channels ||
> +		(asrc_priv->channel_bits < 4 && channels % 2 != 0)) {
>  		dev_err(dev, "can't afford required channels: %d\n", channels);

I feel it'd be better to have another else-if, since the existing
error message is against something else.

+	} else if (asrc_priv->channel_bits < 4 && channels & 1) {
+		/* old version of ASRC has channel_bits = 3 */
+  		dev_err(dev, "does not support odd channel number\n");
+  		ret = -EINVAL;

Alternatively, I feel instead of error-out at here, should we add
a HW constraint or at least fence it off at the beginning of the
hw_params()? This is actually nothing specific to the pair-request
function but a hardware constraint.

^ permalink raw reply

* [PATCH] ASoC: fsl_asrc: add protection for the asrc of older version
From: S.j. Wang @ 2019-03-01  2:32 UTC (permalink / raw)
  To: timur@kernel.org, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com,
	festevam@gmail.com, broonie@kernel.org,
	alsa-devel@alsa-project.org
  Cc: linuxppc-dev@lists.ozlabs.org

There is a constraint for the channel number setting on the
asrc of older version (e.g. imx35), the channel number should
be even, odd number isn't valid.

So add protection when the asrc of older version is used.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
 sound/soc/fsl/fsl_asrc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 528e8b108422..b3b3c5e15ef1 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -109,7 +109,8 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
 	if (index == ASRC_INVALID_PAIR) {
 		dev_err(dev, "all pairs are busy now\n");
 		ret = -EBUSY;
-	} else if (asrc_priv->channel_avail < channels) {
+	} else if (asrc_priv->channel_avail < channels ||
+		(asrc_priv->channel_bits < 4 && channels % 2 != 0)) {
 		dev_err(dev, "can't afford required channels: %d\n", channels);
 		ret = -EINVAL;
 	} else {
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH 7/8] PCI: mediatek: fix a leaked reference by adding missing of_node_put
From: Honghui Zhang @ 2019-03-01  1:59 UTC (permalink / raw)
  To: Wen Yang
  Cc: heiko, hayashi.kunihiko, shawn.lin, minghuan.Lian, paulus,
	thomas.petazzoni, ryder.lee, kishon, linux-rockchip,
	bcm-kernel-feedback-list, linux-arm-kernel, linux-pci, wang.yi59,
	rjui, lorenzo.pieralisi, linux-mediatek, tyreld, matthias.bgg,
	linux-omap, mingkai.hu, roy.zang, sbranden, yamada.masahiro,
	linuxppc-dev, linux-kernel, bhelgaas
In-Reply-To: <1551242443-27300-7-git-send-email-wen.yang99@zte.com.cn>

On Wed, 2019-02-27 at 12:40 +0800, Wen Yang wrote:
> The call to of_get_next_child returns a node pointer with refcount
> incremented thus it must be explicitly decremented after the last
> usage.
> irq_domain_add_linear also calls of_node_get to increase refcount,
> so irq_domain will not be affected when it is released.
> 
> Detected by coccinelle with the following warnings:
> ./drivers/pci/controller/pcie-mediatek.c:577:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 567, but without a corresponding object release within this function.
> ./drivers/pci/controller/pcie-mediatek.c:583:3-9: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 567, but without a corresponding object release within this function.
> ./drivers/pci/controller/pcie-mediatek.c:586:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 567, but without a corresponding object release within this function.
> 
> Signed-off-by: Wen Yang <wen.yang99@zte.com.cn>
> Cc: Ryder Lee <ryder.lee@mediatek.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Matthias Brugger <matthias.bgg@gmail.com>
> Cc: linux-pci@vger.kernel.org
> Cc: linux-mediatek@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> ---
>  drivers/pci/controller/pcie-mediatek.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 55e471c..e91716a 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -572,6 +572,7 @@ static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port,
>  
>  	port->irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
>  						 &intx_domain_ops, port);
> +	of_node_put(pcie_intc_node);
>  	if (!port->irq_domain) {
>  		dev_err(dev, "failed to get INTx IRQ domain\n");
>  		return -ENODEV;

Thanks for fix this.

Acked-by: Honghui Zhang <honghui.zhang@mediatek.com>


^ permalink raw reply

* [PATCH kernel v2] KVM: PPC: Allocate guest TCEs on demand too
From: Alexey Kardashevskiy @ 2019-03-01  1:38 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Alexey Kardashevskiy, kvm-ppc, David Gibson

We already allocate hardware TCE tables in multiple levels and skip
intermediate levels when we can, now it is a turn of the KVM TCE tables.
Thankfully these are allocated already in 2 levels.

This moves the table's last level allocation from the creating helper to
kvmppc_tce_put() and kvm_spapr_tce_fault().

This adds kvmppc_rm_ioba_validate() to do an additional test if
the consequent kvmppc_tce_put() needs a page which has not been allocated;
if this is the case, we bail out to virtual mode handlers.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v2:
* added kvm mutex around alloc_page to prevent races; in both place we
test the pointer, if NULL, then take a lock and check again so on a fast
path we do not take a lock at all


---
For NVLink2 passthrough guests with 128TiB DMA windows and very fragmented
system RAM the difference is gigabytes of RAM.
---
 arch/powerpc/kvm/book3s_64_vio.c    | 29 ++++++------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 69 ++++++++++++++++++++++++++---
 2 files changed, 79 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index f02b049..7eed8c9 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -228,7 +228,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
 	unsigned long i, npages = kvmppc_tce_pages(stt->size);
 
 	for (i = 0; i < npages; i++)
-		__free_page(stt->pages[i]);
+		if (stt->pages[i])
+			__free_page(stt->pages[i]);
 
 	kfree(stt);
 }
@@ -242,6 +243,20 @@ static vm_fault_t kvm_spapr_tce_fault(struct vm_fault *vmf)
 		return VM_FAULT_SIGBUS;
 
 	page = stt->pages[vmf->pgoff];
+	if (!page) {
+		mutex_lock(&stt->kvm->lock);
+		page = stt->pages[vmf->pgoff];
+		if (!page) {
+			page  = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (!page) {
+				mutex_unlock(&stt->kvm->lock);
+				return VM_FAULT_OOM;
+			}
+			stt->pages[vmf->pgoff] = page;
+		}
+		mutex_unlock(&stt->kvm->lock);
+	}
+
 	get_page(page);
 	vmf->page = page;
 	return 0;
@@ -296,7 +311,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	struct kvmppc_spapr_tce_table *siter;
 	unsigned long npages, size = args->size;
 	int ret = -ENOMEM;
-	int i;
 
 	if (!args->size || args->page_shift < 12 || args->page_shift > 34 ||
 		(args->offset + args->size > (ULLONG_MAX >> args->page_shift)))
@@ -320,12 +334,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	stt->kvm = kvm;
 	INIT_LIST_HEAD_RCU(&stt->iommu_tables);
 
-	for (i = 0; i < npages; i++) {
-		stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
-		if (!stt->pages[i])
-			goto fail;
-	}
-
 	mutex_lock(&kvm->lock);
 
 	/* Check this LIOBN hasn't been previously allocated */
@@ -352,11 +360,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	if (ret >= 0)
 		return ret;
 
- fail:
-	for (i = 0; i < npages; i++)
-		if (stt->pages[i])
-			__free_page(stt->pages[i]);
-
 	kfree(stt);
  fail_acct:
 	kvmppc_account_memlimit(kvmppc_stt_pages(npages), false);
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 2206bc7..a0912d5 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -158,23 +158,76 @@ static u64 *kvmppc_page_address(struct page *page)
 	return (u64 *) page_address(page);
 }
 
+/*
+ * TCEs pages are allocated in kvmppc_tce_put() which won't be able to do so
+ * in real mode.
+ * Check if kvmppc_tce_put() can succeed in real mode, i.e. a TCEs page is
+ * allocated or not required (when clearing a tce entry).
+ */
+static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
+		unsigned long ioba, unsigned long npages, bool clearing)
+{
+	unsigned long i, sttpage, sttpages;
+	unsigned long ret = kvmppc_ioba_validate(stt, ioba, npages);
+
+	if (ret)
+		return ret;
+	/*
+	 * clearing==true says kvmppc_tce_put won't be allocating pages
+	 * for empty tces.
+	 */
+	if (clearing)
+		return H_SUCCESS;
+
+	sttpage = ((ioba >> stt->page_shift) - stt->offset) / TCES_PER_PAGE;
+	sttpages = (npages + TCES_PER_PAGE - 1) / TCES_PER_PAGE;
+	for (i = sttpage; i < sttpage + sttpages; ++i)
+		if (!stt->pages[i])
+			return H_TOO_HARD;
+
+	return H_SUCCESS;
+}
+
 /*
  * Handles TCE requests for emulated devices.
  * Puts guest TCE values to the table and expects user space to convert them.
  * Called in both real and virtual modes.
  * Cannot fail so kvmppc_tce_validate must be called before it.
  *
- * WARNING: This will be called in real-mode on HV KVM and virtual
- *          mode on PR KVM
+ * WARNING: This will be called in real-mode on HV HPT KVM and virtual
+ *          mode on PR KVM or HV radix KVM
  */
 void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
 		unsigned long idx, unsigned long tce)
 {
 	struct page *page;
 	u64 *tbl;
+	unsigned long sttpage;
 
 	idx -= stt->offset;
-	page = stt->pages[idx / TCES_PER_PAGE];
+	sttpage = idx / TCES_PER_PAGE;
+	page = stt->pages[sttpage];
+
+	if (!page) {
+		/* We allow any TCE, not just with read|write permissions */
+		if (!tce)
+			return;
+		/*
+		 * We must not end up here in real mode,
+		 * kvmppc_rm_ioba_validate() takes care of this.
+		 */
+		mutex_lock(&stt->kvm->lock);
+		page = stt->pages[sttpage];
+		if (!page) {
+			page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (WARN_ON_ONCE(!page)) {
+				mutex_unlock(&stt->kvm->lock);
+				return;
+			}
+			stt->pages[sttpage] = page;
+		}
+		mutex_unlock(&stt->kvm->lock);
+	}
 	tbl = kvmppc_page_address(page);
 
 	tbl[idx % TCES_PER_PAGE] = tce;
@@ -381,7 +434,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (!stt)
 		return H_TOO_HARD;
 
-	ret = kvmppc_ioba_validate(stt, ioba, 1);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, 1, tce == 0);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -480,7 +533,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 	if (tce_list & (SZ_4K - 1))
 		return H_PARAMETER;
 
-	ret = kvmppc_ioba_validate(stt, ioba, npages);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, false);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -583,7 +636,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
 	if (!stt)
 		return H_TOO_HARD;
 
-	ret = kvmppc_ioba_validate(stt, ioba, npages);
+	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, tce_value == 0);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -635,6 +688,10 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 
 	idx = (ioba >> stt->page_shift) - stt->offset;
 	page = stt->pages[idx / TCES_PER_PAGE];
+	if (!page) {
+		vcpu->arch.regs.gpr[4] = 0;
+		return H_SUCCESS;
+	}
 	tbl = (u64 *)page_address(page);
 
 	vcpu->arch.regs.gpr[4] = tbl[idx % TCES_PER_PAGE];
-- 
2.17.1


^ permalink raw reply related

* Re: [RFC PATCH v2 09/14] watchdog/hardlockup: Make arch_touch_nmi_watchdog() to hpet-based implementation
From: Ricardo Neri @ 2019-03-01  1:17 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Rafael J. Wysocki, Peter Zijlstra, Alexei Starovoitov,
	Kai-Heng Feng, Paul Mackerras, H. Peter Anvin, sparclinux,
	Ingo Molnar, Christoffer Dall, Davidlohr Bueso, Ashok Raj, x86,
	David Rientjes, Andi Kleen, Waiman Long, Borislav Petkov,
	Don Zickus, Ravi V. Shankar, Konrad Rzeszutek Wilk, Marc Zyngier,
	Frederic Weisbecker, Nicholas Piggin, Ricardo Neri,
	Byungchul Park, Mathieu Desnoyers, Josh Poimboeuf,
	Thomas Gleixner, Tony Luck, Babu Moger, Randy Dunlap,
	linux-kernel, Luis R. Rodriguez, Masami Hiramatsu,
	Philippe Ombredanne, Colin Ian King, Andrew Morton, linuxppc-dev,
	David S. Miller
In-Reply-To: <20190227161758.GE4072@linux.ibm.com>

On Wed, Feb 27, 2019 at 08:17:58AM -0800, Paul E. McKenney wrote:
> On Wed, Feb 27, 2019 at 08:05:13AM -0800, Ricardo Neri wrote:
> > CPU architectures that have an NMI watchdog use arch_touch_nmi_watchdog()
> > to briefly ignore the hardlockup detector. If the architecture does not
> > have an NMI watchdog, one can be constructed using a source of non-
> > maskable interrupts. In this case, arch_touch_nmi_watchdog() is common
> > to any underlying hardware resource used to drive the detector and needs
> > to be available to other kernel subsystems if hardware different from perf
> > drives the detector.
> > 
> > There exists perf-based and HPET-based implementations. Make it available
> > to the latter.
> > 
> > For clarity, wrap this function in a separate preprocessor conditional
> > from functions which are truly specific to the perf-based implementation.
> > 
> > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > Cc: Ashok Raj <ashok.raj@intel.com>
> > Cc: Andi Kleen <andi.kleen@intel.com>
> > Cc: Tony Luck <tony.luck@intel.com>
> > Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> > Cc: Don Zickus <dzickus@redhat.com>
> > Cc: Nicholas Piggin <npiggin@gmail.com>
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Frederic Weisbecker <frederic@kernel.org>
> > Cc: Alexei Starovoitov <ast@kernel.org>
> > Cc: Babu Moger <babu.moger@oracle.com>
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > Cc: Masami Hiramatsu <mhiramat@kernel.org>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Philippe Ombredanne <pombredanne@nexb.com>
> > Cc: Colin Ian King <colin.king@canonical.com>
> > Cc: Byungchul Park <byungchul.park@lge.com>
> > Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> > Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
> > Cc: Waiman Long <longman@redhat.com>
> > Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> > Cc: Randy Dunlap <rdunlap@infradead.org>
> > Cc: Davidlohr Bueso <dave@stgolabs.net>
> > Cc: Christoffer Dall <cdall@linaro.org>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > Cc: David Rientjes <rientjes@google.com>
> > Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
> > Cc: x86@kernel.org
> > Cc: sparclinux@vger.kernel.org
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
> > ---
> >  include/linux/nmi.h | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/nmi.h b/include/linux/nmi.h
> > index 5a8b19749769..bf5ebcfdd590 100644
> > --- a/include/linux/nmi.h
> > +++ b/include/linux/nmi.h
> > @@ -94,8 +94,16 @@ static inline void hardlockup_detector_disable(void) {}
> >  # define NMI_WATCHDOG_SYSCTL_PERM	0444
> >  #endif
> > 
> > -#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
> > +#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) || \
> > +    defined(CONFIG_X86_HARDLOCKUP_DETECTOR_HPET)
> 
> Why not instead make CONFIG_X86_HARDLOCKUP_DETECTOR_HPET select
> CONFIG_HARDLOCKUP_DETECTOR_PERF?  Keep the arch-specific details
> in the arch-specific files and all that.

Thanks for your feedback, Paul! The HPET implementation does not use
perf. Thus, in my opinion is not correct for the HPET HLD to select
the perf implementation. Patch 8 of this series splits the perf-specific
code and the generic hardlockup detector code. Does this make sense?

Thanks and BR,
Ricardo

^ permalink raw reply

* Re: [PATCH 7/8] dt-bindings: iio/counter: ftm-quaddec: add poll-interval parameter
From: Rob Herring @ 2019-02-28 19:47 UTC (permalink / raw)
  To: Patrick Havelange
  Cc: linux-arm-kernel, devicetree, Lars-Peter Clausen,
	Patrick Havelange, linux-pwm, linux-iio, linux-kernel,
	Linus Walleij, Daniel Lezcano, William Breathitt Gray, Li Yang,
	Thierry Reding, Esben Haabendal, Peter Meerwald-Stadler,
	Hartmut Knaack, Thomas Gleixner, linuxppc-dev, Jonathan Cameron
In-Reply-To: <20190218140321.19166-7-patrick.havelange@essensium.com>

On Mon, 18 Feb 2019 15:03:20 +0100, Patrick Havelange wrote:
> New optional parameter supported by updated driver.
> 
> Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>
> Reviewed-by: Esben Haabendal <esben@haabendal.dk>
> ---
>  .../devicetree/bindings/iio/counter/ftm-quaddec.txt       | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v7 16/22] powerpc: define syscall_get_error()
From: Dmitry V. Levin @ 2019-02-28 19:39 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev
  Cc: Eugene Syromyatnikov, Oleg Nesterov, Elvira Khabirova,
	Paul Mackerras, Andy Lutomirski, linux-kernel
In-Reply-To: <20190107025417.GP1207@altlinux.org>

syscall_get_error() is required to be implemented on this
architecture in addition to already implemented syscall_get_nr(),
syscall_get_arguments(), syscall_get_return_value(), and
syscall_get_arch() functions in order to extend the generic
ptrace API with PTRACE_GET_SYSCALL_INFO request.

Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Elvira Khabirova <lineprinter@altlinux.org>
Cc: Eugene Syromyatnikov <esyr@redhat.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---

This is just a gentle ping, the patch is unchanged.

Notes:
    v7: unchanged
    v6: unchanged
    v5:
    This change has been tested with
    tools/testing/selftests/ptrace/get_syscall_info.c and strace,
    so it's correct from PTRACE_GET_SYSCALL_INFO point of view.
    
    This cast doubts on commit v4.3-rc1~86^2~81 that changed
    syscall_set_return_value() in a way that doesn't quite match
    syscall_get_error(), but syscall_set_return_value() is out
    of scope of this series, so I'll just let you know my concerns.

 arch/powerpc/include/asm/syscall.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 1a0e7a8b1c81..b522781ad7c0 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -38,6 +38,16 @@ static inline void syscall_rollback(struct task_struct *task,
 	regs->gpr[3] = regs->orig_gpr3;
 }
 
+static inline long syscall_get_error(struct task_struct *task,
+				     struct pt_regs *regs)
+{
+	/*
+	 * If the system call failed,
+	 * regs->gpr[3] contains a positive ERRORCODE.
+	 */
+	return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0;
+}
+
 static inline long syscall_get_return_value(struct task_struct *task,
 					    struct pt_regs *regs)
 {
-- 
ldv

^ permalink raw reply related

* Re: [PATCH v4 9/9] powerpc/64s: Implement KUAP for Radix MMU
From: kbuild test robot @ 2019-02-28 19:43 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, npiggin, kbuild-all, akshay.adiga
In-Reply-To: <20190228144917.16876-9-mpe@ellerman.id.au>

[-- Attachment #1: Type: text/plain, Size: 3532 bytes --]

Hi Russell,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[cannot apply to v5.0-rc8 next-20190228]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Michael-Ellerman/powerpc-powernv-idle-Restore-IAMR-after-idle/20190228-235025
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-ppc64e_defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 8.2.0-11) 8.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.2.0 make.cross ARCH=powerpc 

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/entry_64.S: Assembler messages:
>> arch/powerpc/kernel/entry_64.S:279: Error: unrecognized opcode: `kuap_check_amr'
>> arch/powerpc/kernel/entry_64.S:317: Error: unrecognized opcode: `kuap_restore_amr'
   arch/powerpc/kernel/entry_64.S:606: Error: unrecognized opcode: `kuap_check_amr'

vim +279 arch/powerpc/kernel/entry_64.S

   250	
   251		ld	r9,TI_FLAGS(r12)
   252		li	r11,-MAX_ERRNO
   253		andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
   254		bne-	.Lsyscall_exit_work
   255	
   256		andi.	r0,r8,MSR_FP
   257		beq 2f
   258	#ifdef CONFIG_ALTIVEC
   259		andis.	r0,r8,MSR_VEC@h
   260		bne	3f
   261	#endif
   262	2:	addi    r3,r1,STACK_FRAME_OVERHEAD
   263		bl	restore_math
   264		ld	r8,_MSR(r1)
   265		ld	r3,RESULT(r1)
   266		li	r11,-MAX_ERRNO
   267	
   268	3:	cmpld	r3,r11
   269		ld	r5,_CCR(r1)
   270		bge-	.Lsyscall_error
   271	.Lsyscall_error_cont:
   272		ld	r7,_NIP(r1)
   273	BEGIN_FTR_SECTION
   274		stdcx.	r0,0,r1			/* to clear the reservation */
   275	END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
   276		andi.	r6,r8,MSR_PR
   277		ld	r4,_LINK(r1)
   278	
 > 279		kuap_check_amr r11
   280	
   281	#ifdef CONFIG_PPC_BOOK3S
   282		/*
   283		 * Clear MSR_RI, MSR_EE is already and remains disabled. We could do
   284		 * this later, but testing shows that doing it here causes less slow
   285		 * down than doing it closer to the rfid.
   286		 */
   287		li	r11,0
   288		mtmsrd	r11,1
   289	#endif
   290	
   291		beq-	1f
   292		ACCOUNT_CPU_USER_EXIT(r13, r11, r12)
   293	
   294	BEGIN_FTR_SECTION
   295		HMT_MEDIUM_LOW
   296	END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
   297	
   298	#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
   299		std	r8, PACATMSCRATCH(r13)
   300	#endif
   301	
   302		/*
   303		 * We don't need to restore AMR on the way back to userspace for KUAP.
   304		 * The value of AMR only matters while we're in the kernel.
   305		 */
   306		ld	r13,GPR13(r1)	/* only restore r13 if returning to usermode */
   307		ld	r2,GPR2(r1)
   308		ld	r1,GPR1(r1)
   309		mtlr	r4
   310		mtcr	r5
   311		mtspr	SPRN_SRR0,r7
   312		mtspr	SPRN_SRR1,r8
   313		RFI_TO_USER
   314		b	.	/* prevent speculative execution */
   315	
   316	1:	/* exit to kernel */
 > 317		kuap_restore_amr r2
   318	
   319		ld	r2,GPR2(r1)
   320		ld	r1,GPR1(r1)
   321		mtlr	r4
   322		mtcr	r5
   323		mtspr	SPRN_SRR0,r7
   324		mtspr	SPRN_SRR1,r8
   325		RFI_TO_KERNEL
   326		b	.	/* prevent speculative execution */
   327	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 16151 bytes --]

^ permalink raw reply

* Re: [PATCH V5 0/5] NestMMU pte upgrade workaround for mprotect
From: Andrew Morton @ 2019-02-28 19:39 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: x86, npiggin, linux-mm, paulus, linuxppc-dev
In-Reply-To: <87k1hltxoc.fsf@linux.ibm.com>

On Wed, 27 Feb 2019 14:28:43 +0530 "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> wrote:

> Andrew Morton <akpm@linux-foundation.org> writes:
> 
> > [patch 1/5]: unreviewed and has unaddressed comments from mpe.
> > [patch 2/5]: ditto
> > [patch 3/5]: ditto
> > [patch 4/5]: seems ready
> > [patch 5/5]: reviewed by mpe, but appears to need more work
> 
> That was mostly variable naming preferences. I like the christmas
> tree style not the inverted christmas tree. There is one detail about
> commit message, which indicate the change may be required by other
> architecture too. Was not sure whether that needed a commit message
> update.
> 
> I didn't send an updated series because after replying to most of them I
> didn't find a strong request to get the required changes in. If you want
> me update the series with this variable name ordering and commit message
> update I can send a new series today.
> 

OK, minor stuff.

The patches have been in -next for a month, which is good but we really
should get some review of the first three.


^ permalink raw reply

* [PATCH 6/6] arm64: ptrace: add support for syscall emulation
From: Sudeep Holla @ 2019-02-28 18:32 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel, linuxppc-dev
  Cc: Haibo Xu, Steve Capper, jdike, Sudeep Holla, Will Deacon,
	Oleg Nesterov, Bin Lu, Richard Weinberger, Ingo Molnar,
	Paul Mackerras, Catalin Marinas, Thomas Gleixner
In-Reply-To: <20190228183220.15626-1-sudeep.holla@arm.com>

Add PTRACE_SYSEMU and PTRACE_SYSEMU_SINGLESTEP support on arm64.
We can just make sure of the generic ptrace_syscall_enter hook to
support PTRACE_SYSEMU. We don't need any special handling for
PTRACE_SYSEMU_SINGLESTEP.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/arm64/include/asm/thread_info.h | 5 ++++-
 arch/arm64/kernel/ptrace.c           | 3 +++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index bbca68b54732..c86aeb6379d5 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -75,6 +75,7 @@ void arch_release_task_struct(struct task_struct *tsk);
  *  TIF_SYSCALL_TRACE	- syscall trace active
  *  TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
  *  TIF_SYSCALL_AUDIT	- syscall auditing
+ *  TIF_SYSCALL_EMU     - syscall emulation active
  *  TIF_SECOMP		- syscall secure computing
  *  TIF_SIGPENDING	- signal pending
  *  TIF_NEED_RESCHED	- rescheduling necessary
@@ -92,6 +93,7 @@ void arch_release_task_struct(struct task_struct *tsk);
 #define TIF_SYSCALL_AUDIT	9
 #define TIF_SYSCALL_TRACEPOINT	10
 #define TIF_SECCOMP		11
+#define TIF_SYSCALL_EMU		12
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_FREEZE		19
 #define TIF_RESTORE_SIGMASK	20
@@ -110,6 +112,7 @@ void arch_release_task_struct(struct task_struct *tsk);
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
+#define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
 #define _TIF_UPROBE		(1 << TIF_UPROBE)
 #define _TIF_FSCHECK		(1 << TIF_FSCHECK)
 #define _TIF_32BIT		(1 << TIF_32BIT)
@@ -121,7 +124,7 @@ void arch_release_task_struct(struct task_struct *tsk);
 
 #define _TIF_SYSCALL_WORK	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
 				 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
-				 _TIF_NOHZ)
+				 _TIF_NOHZ | _TIF_SYSCALL_EMU)
 
 #define INIT_THREAD_INFO(tsk)						\
 {									\
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index ddaea0fd2fa4..c377ce597f92 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1672,6 +1672,9 @@ static void tracehook_report_syscall(struct pt_regs *regs,
 
 int syscall_trace_enter(struct pt_regs *regs)
 {
+	if (unlikely(ptrace_syscall_enter(regs)))
+		return -1;
+
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH 5/6] arm64: add PTRACE_SYSEMU{, SINGLESTEP} definations to uapi headers
From: Sudeep Holla @ 2019-02-28 18:32 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel, linuxppc-dev
  Cc: Haibo Xu, Steve Capper, jdike, Sudeep Holla, Will Deacon,
	Oleg Nesterov, Bin Lu, Richard Weinberger, Ingo Molnar,
	Paul Mackerras, Catalin Marinas, Thomas Gleixner
In-Reply-To: <20190228183220.15626-1-sudeep.holla@arm.com>

x86 and um use 31 and 32 for PTRACE_SYSEMU and PTRACE_SYSEMU_SINGLESTEP
while powerpc uses different value maybe for legacy reasons.

Though handling of PTRACE_SYSEMU can be made architecture independent,
it's hard to make these definations generic. To add to this existing
mess few architectures like arm, c6x and sh use 31 for PTRACE_GETFDPIC
(get the ELF fdpic loadmap address). It's not possible to move the
definations to generic headers.

So we unfortunately have to duplicate the same defination to ARM64 if
we need to support PTRACE_SYSEMU.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/arm64/include/uapi/asm/ptrace.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 28d77c9ed531..8478b9007f9e 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -62,6 +62,9 @@
 #define PSR_x		0x0000ff00	/* Extension		*/
 #define PSR_c		0x000000ff	/* Control		*/
 
+/* syscall emulation path in ptrace */
+#define PTRACE_SYSEMU		  31
+#define PTRACE_SYSEMU_SINGLESTEP  32
 
 #ifndef __ASSEMBLY__
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH 4/6] powerpc: use common ptrace_syscall_enter hook to handle _TIF_SYSCALL_EMU
From: Sudeep Holla @ 2019-02-28 18:32 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel, linuxppc-dev
  Cc: Haibo Xu, Steve Capper, jdike, Sudeep Holla, Will Deacon,
	Oleg Nesterov, Bin Lu, Richard Weinberger, Ingo Molnar,
	Paul Mackerras, Catalin Marinas, Thomas Gleixner
In-Reply-To: <20190228183220.15626-1-sudeep.holla@arm.com>

Now that we have a new hook ptrace_syscall_enter that can be called from
syscall entry code and it handles PTRACE_SYSEMU in generic code, we
can do some cleanup using the same in do_syscall_trace_enter.

Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/powerpc/kernel/ptrace.c | 50 ++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cb7e1439cafb..978cd2aac29e 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -3264,37 +3264,31 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 {
 	u32 flags;
 
-	user_exit();
-
-	flags = READ_ONCE(current_thread_info()->flags) &
-		(_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
+	if (unlikely(ptrace_syscall_enter(regs))) {
+		/*
+		 * A nonzero return code from tracehook_report_syscall_entry()
+		 * tells us to prevent the syscall execution, but we are not
+		 * going to execute it anyway.
+		 *
+		 * Returning -1 will skip the syscall execution. We want to
+		 * avoid clobbering any registers, so we don't goto the skip
+		 * label below.
+		 */
+		return -1;
+	}
 
-	if (flags) {
-		int rc = tracehook_report_syscall_entry(regs);
+	user_exit();
 
-		if (unlikely(flags & _TIF_SYSCALL_EMU)) {
-			/*
-			 * A nonzero return code from
-			 * tracehook_report_syscall_entry() tells us to prevent
-			 * the syscall execution, but we are not going to
-			 * execute it anyway.
-			 *
-			 * Returning -1 will skip the syscall execution. We want
-			 * to avoid clobbering any registers, so we don't goto
-			 * the skip label below.
-			 */
-			return -1;
-		}
+	flags = READ_ONCE(current_thread_info()->flags) & _TIF_SYSCALL_TRACE;
 
-		if (rc) {
-			/*
-			 * The tracer decided to abort the syscall. Note that
-			 * the tracer may also just change regs->gpr[0] to an
-			 * invalid syscall number, that is handled below on the
-			 * exit path.
-			 */
-			goto skip;
-		}
+	if (flags && tracehook_report_syscall_entry(regs)) {
+		/*
+		 * The tracer decided to abort the syscall. Note that
+		 * the tracer may also just change regs->gpr[0] to an
+		 * invalid syscall number, that is handled below on the
+		 * exit path.
+		 */
+		goto skip;
 	}
 
 	/* Run seccomp after ptrace; allow it to set gpr[3]. */
-- 
2.17.1


^ permalink raw reply related

* [PATCH 1/6] ptrace: move clearing of TIF_SYSCALL_EMU flag to core
From: Sudeep Holla @ 2019-02-28 18:32 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel, linuxppc-dev
  Cc: Haibo Xu, Steve Capper, jdike, Sudeep Holla, Will Deacon,
	Oleg Nesterov, Bin Lu, Richard Weinberger, Ingo Molnar,
	Paul Mackerras, Catalin Marinas, Thomas Gleixner
In-Reply-To: <20190228183220.15626-1-sudeep.holla@arm.com>

While the TIF_SYSCALL_EMU is set in ptrace_resume independent of any
architecture, currently only powerpc and x86 unset the TIF_SYSCALL_EMU
flag in ptrace_disable which gets called from ptrace_detach.

Let's move the clearing of TIF_SYSCALL_EMU flag to ptrace_detach after
we return from ptrace_disable to ensure there's no change in the flow.

Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/powerpc/kernel/ptrace.c | 1 -
 arch/x86/kernel/ptrace.c     | 3 ---
 kernel/ptrace.c              | 4 ++++
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cdd5d1d3ae41..cb7e1439cafb 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -2508,7 +2508,6 @@ void ptrace_disable(struct task_struct *child)
 {
 	/* make sure the single step bit is not set. */
 	user_disable_single_step(child);
-	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
 }
 
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 4b8ee05dd6ad..45792dbd2443 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -746,9 +746,6 @@ static int ioperm_get(struct task_struct *target,
 void ptrace_disable(struct task_struct *child)
 {
 	user_disable_single_step(child);
-#ifdef TIF_SYSCALL_EMU
-	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-#endif
 }
 
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 771e93f9c43f..4fa3b7f4c3c7 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -534,6 +534,10 @@ static int ptrace_detach(struct task_struct *child, unsigned int data)
 	/* Architecture-specific hardware disable .. */
 	ptrace_disable(child);
 
+#ifdef TIF_SYSCALL_EMU
+	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
+#endif
+
 	write_lock_irq(&tasklist_lock);
 	/*
 	 * We rely on ptrace_freeze_traced(). It can't be killed and
-- 
2.17.1


^ permalink raw reply related

* [PATCH 0/6] ptrace: consolidate PTRACE_SYSEMU handling and add support for arm64
From: Sudeep Holla @ 2019-02-28 18:32 UTC (permalink / raw)
  To: x86, linux-arm-kernel, linux-kernel, linuxppc-dev
  Cc: Haibo Xu, Steve Capper, jdike, Sudeep Holla, Will Deacon,
	Oleg Nesterov, Bin Lu, Richard Weinberger, Ingo Molnar,
	Paul Mackerras, Catalin Marinas, Thomas Gleixner

Hi,

This patchset evolved from the discussion in the thread[0][1]. When we
wanted to add PTRACE_SYSEMU support to ARM64, we thought instead of
duplicating what other architectures like x86 and powerpc have done,
let consolidate the existing support and move it to the core as there's
nothing arch specific in it.

So this is the first attempt to the same.

Regards,
Sudeep

[0] https://patchwork.kernel.org/patch/10585505/
[1] https://patchwork.kernel.org/patch/10675237/

Sudeep Holla (6):
  ptrace: move clearing of TIF_SYSCALL_EMU flag to core
  ptrace: introduce ptrace_syscall_enter to consolidate PTRACE_SYSEMU handling
  x86: clean up _TIF_SYSCALL_EMU handling using ptrace_syscall_enter hook
  powerpc: use common ptrace_syscall_enter hook to handle _TIF_SYSCALL_EMU
  arm64: add PTRACE_SYSEMU{,SINGLESTEP} definations to uapi headers
  arm64: ptrace: add support for syscall emulation

 arch/arm64/include/asm/thread_info.h |  5 ++-
 arch/arm64/include/uapi/asm/ptrace.h |  3 ++
 arch/arm64/kernel/ptrace.c           |  3 ++
 arch/powerpc/kernel/ptrace.c         | 51 ++++++++++++----------------
 arch/x86/entry/common.c              | 22 +++---------
 arch/x86/kernel/ptrace.c             |  3 --
 include/linux/ptrace.h               |  1 +
 kernel/ptrace.c                      | 20 +++++++++++
 8 files changed, 57 insertions(+), 51 deletions(-)

--
2.17.1


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox