[v4,2/9] s390/mm: Introduce gmap_pmdp_xchg
diff mbox

Message ID 20180627135510.117945-3-frankja@linux.ibm.com
State New
Headers show

Commit Message

Janosch Frank June 27, 2018, 1:55 p.m. UTC
From: Janosch Frank <frankja@linux.vnet.ibm.com>

When changing guest pmds, we don't need to take care of the
corresponding host pmd. This means, we don't need to flush the host
TLB entries and we don't need to notify on all gmaps.

Let's introduce a function, that exchanges a pmd and takes care of the
necessary flushing.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
---
 arch/s390/mm/gmap.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Comments

Christian Borntraeger June 28, 2018, 9:17 a.m. UTC | #1
On 06/27/2018 03:55 PM, Janosch Frank wrote:
> From: Janosch Frank <frankja@linux.vnet.ibm.com>
> 
> When changing guest pmds, we don't need to take care of the
> corresponding host pmd. This means, we don't need to flush the host
> TLB entries and we don't need to notify on all gmaps.
> 
> Let's introduce a function, that exchanges a pmd and takes care of the
> necessary flushing.
> 
> Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
> ---
>  arch/s390/mm/gmap.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
> index bae0b4f674b5..f5b48426dde8 100644
> --- a/arch/s390/mm/gmap.c
> +++ b/arch/s390/mm/gmap.c
> @@ -23,6 +23,9 @@
>  
>  #define GMAP_SHADOW_FAKE_TABLE 1ULL
>  
> +static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *old, pmd_t new,
> +			   unsigned long gaddr);
> +
>  /**
>   * gmap_alloc - allocate and initialize a guest address space
>   * @mm: pointer to the parent mm_struct
> @@ -2165,6 +2168,29 @@ void ptep_notify(struct mm_struct *mm, unsigned long vmaddr,
>  }
>  EXPORT_SYMBOL_GPL(ptep_notify);
>  
> +/**
> + * gmap_pmdp_xchg - exchange a gmap pmd with another
> + * @gmap: pointer to the guest address space structure
> + * @pmdp: pointer to the pmd entry
> + * @new: replacement entry
> + * @gaddr: the affected guest address
> + *
> + * This function is assumed to be called with the guest_table_lock
> + * held.
> + */
> +static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new,
> +			   unsigned long gaddr)
> +{
> +	if (MACHINE_HAS_TLB_GUEST)
> +		__pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce,
> +			    IDTE_GLOBAL);

do we need an else here?

> +	if (MACHINE_HAS_IDTE)
> +		__pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL);


> +	else
> +		__pmdp_csp(pmdp);
> +	*pmdp = new;
> +}
> +
>  static inline void thp_split_mm(struct mm_struct *mm)
>  {
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>
Janosch Frank June 28, 2018, 10:51 a.m. UTC | #2
On 28.06.2018 11:17, Christian Borntraeger wrote:
> 
> 
> On 06/27/2018 03:55 PM, Janosch Frank wrote:
>> From: Janosch Frank <frankja@linux.vnet.ibm.com>
>>
>> When changing guest pmds, we don't need to take care of the
>> corresponding host pmd. This means, we don't need to flush the host
>> TLB entries and we don't need to notify on all gmaps.
>>
>> Let's introduce a function, that exchanges a pmd and takes care of the
>> necessary flushing.
>>
>> Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
>> ---
>>  arch/s390/mm/gmap.c | 26 ++++++++++++++++++++++++++
>>  1 file changed, 26 insertions(+)
>>
>> diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
>> index bae0b4f674b5..f5b48426dde8 100644
>> --- a/arch/s390/mm/gmap.c
>> +++ b/arch/s390/mm/gmap.c
>> @@ -23,6 +23,9 @@
>>  
>>  #define GMAP_SHADOW_FAKE_TABLE 1ULL
>>  
>> +static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *old, pmd_t new,
>> +			   unsigned long gaddr);
>> +
>>  /**
>>   * gmap_alloc - allocate and initialize a guest address space
>>   * @mm: pointer to the parent mm_struct
>> @@ -2165,6 +2168,29 @@ void ptep_notify(struct mm_struct *mm, unsigned long vmaddr,
>>  }
>>  EXPORT_SYMBOL_GPL(ptep_notify);
>>  
>> +/**
>> + * gmap_pmdp_xchg - exchange a gmap pmd with another
>> + * @gmap: pointer to the guest address space structure
>> + * @pmdp: pointer to the pmd entry
>> + * @new: replacement entry
>> + * @gaddr: the affected guest address
>> + *
>> + * This function is assumed to be called with the guest_table_lock
>> + * held.
>> + */
>> +static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new,
>> +			   unsigned long gaddr)
>> +{
>> +	if (MACHINE_HAS_TLB_GUEST)
>> +		__pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce,
>> +			    IDTE_GLOBAL);
> 
> do we need an else here?

Good catch
It would be better to have one and avoid the second IDTE.

> 
>> +	if (MACHINE_HAS_IDTE)
>> +		__pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL);
> 
> 
>> +	else
>> +		__pmdp_csp(pmdp);
>> +	*pmdp = new;
>> +}
>> +
>>  static inline void thp_split_mm(struct mm_struct *mm)
>>  {
>>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>>
>

Patch
diff mbox

diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index bae0b4f674b5..f5b48426dde8 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -23,6 +23,9 @@ 
 
 #define GMAP_SHADOW_FAKE_TABLE 1ULL
 
+static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *old, pmd_t new,
+			   unsigned long gaddr);
+
 /**
  * gmap_alloc - allocate and initialize a guest address space
  * @mm: pointer to the parent mm_struct
@@ -2165,6 +2168,29 @@  void ptep_notify(struct mm_struct *mm, unsigned long vmaddr,
 }
 EXPORT_SYMBOL_GPL(ptep_notify);
 
+/**
+ * gmap_pmdp_xchg - exchange a gmap pmd with another
+ * @gmap: pointer to the guest address space structure
+ * @pmdp: pointer to the pmd entry
+ * @new: replacement entry
+ * @gaddr: the affected guest address
+ *
+ * This function is assumed to be called with the guest_table_lock
+ * held.
+ */
+static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new,
+			   unsigned long gaddr)
+{
+	if (MACHINE_HAS_TLB_GUEST)
+		__pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce,
+			    IDTE_GLOBAL);
+	if (MACHINE_HAS_IDTE)
+		__pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL);
+	else
+		__pmdp_csp(pmdp);
+	*pmdp = new;
+}
+
 static inline void thp_split_mm(struct mm_struct *mm)
 {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE