Re: [RFCv2 05/37] s390/mm: provide memory management functions for protected KVM guests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 4 Feb 2020 11:57:38 +0100
Cornelia Huck <cohuck@xxxxxxxxxx> wrote:

> On Mon,  3 Feb 2020 08:19:25 -0500
> Christian Borntraeger <borntraeger@xxxxxxxxxx> wrote:
> 
> > From: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx>
> > 
> > This provides the basic ultravisor calls and page table handling to
> > cope with secure guests.  
> 
> I'll leave reviewing the mm stuff to somebody actually familiar with
> mm; only some other comments from me.
> 
> > 
> > Co-authored-by: Ulrich Weigand <Ulrich.Weigand@xxxxxxxxxx>
> > Signed-off-by: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx>
> > ---
> >  arch/s390/include/asm/gmap.h        |   2 +
> >  arch/s390/include/asm/mmu.h         |   2 +
> >  arch/s390/include/asm/mmu_context.h |   1 +
> >  arch/s390/include/asm/page.h        |   5 +
> >  arch/s390/include/asm/pgtable.h     |  34 +++++-
> >  arch/s390/include/asm/uv.h          |  59 ++++++++++
> >  arch/s390/kernel/uv.c               | 170
> > ++++++++++++++++++++++++++++ 7 files changed, 268 insertions(+), 5
> > deletions(-)
> > 
> > diff --git a/arch/s390/include/asm/gmap.h
> > b/arch/s390/include/asm/gmap.h index 37f96b6f0e61..f2ab8b6d4b57
> > 100644 --- a/arch/s390/include/asm/gmap.h
> > +++ b/arch/s390/include/asm/gmap.h
> > @@ -9,6 +9,7 @@
> >  #ifndef _ASM_S390_GMAP_H
> >  #define _ASM_S390_GMAP_H
> >  
> > +#include <linux/radix-tree.h>
> >  #include <linux/refcount.h>
> >  
> >  /* Generic bits for GMAP notification on DAT table entry changes.
> > */ @@ -61,6 +62,7 @@ struct gmap {
> >  	spinlock_t shadow_lock;
> >  	struct gmap *parent;
> >  	unsigned long orig_asce;
> > +	unsigned long se_handle;  
> 
> This is a deviation from the "protected virtualization" naming scheme
> used in the previous patches, but I understand that the naming of this
> whole feature is still in flux :) (Would still be nice to have it
> consistent, though.)
> 
> However, I think I'd prefer something named based on protected
> virtualization: the se_* stuff here just tends to make me think of
> SELinux...
> 
> >  	int edat_level;
> >  	bool removed;
> >  	bool initialized;
> > diff --git a/arch/s390/include/asm/mmu.h
> > b/arch/s390/include/asm/mmu.h index bcfb6371086f..984026cb3608
> > 100644 --- a/arch/s390/include/asm/mmu.h
> > +++ b/arch/s390/include/asm/mmu.h
> > @@ -16,6 +16,8 @@ typedef struct {
> >  	unsigned long asce;
> >  	unsigned long asce_limit;
> >  	unsigned long vdso_base;
> > +	/* The mmu context belongs to a secure guest. */
> > +	atomic_t is_se;  
> 
> Here as well.
> 
> >  	/*
> >  	 * The following bitfields need a down_write on the mm
> >  	 * semaphore when they are written to. As they are only  
> 
> (...)
> 
> > @@ -520,6 +521,15 @@ static inline int mm_has_pgste(struct
> > mm_struct *mm) return 0;
> >  }
> >  
> > +static inline int mm_is_se(struct mm_struct *mm)
> > +{
> > +#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
> > +	if (unlikely(atomic_read(&mm->context.is_se)))
> > +		return 1;
> > +#endif
> > +	return 0;
> > +}  
> 
> I'm wondering how big of an overhead we actually have because we need
> to check the flag here if the feature is enabled. We have an extra
> check in a few functions anyway, even if protected virt is not
> configured in. Given that distributions would likely want to enable
> the feature in their kernels, I'm currently tending towards dropping
> the extra config option.
> 
> > +
> >  static inline int mm_alloc_pgste(struct mm_struct *mm)
> >  {
> >  #ifdef CONFIG_PGSTE  
> 
> (...)
> 
> > diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
> > index f7778493e829..136c60a8e3ca 100644
> > --- a/arch/s390/kernel/uv.c
> > +++ b/arch/s390/kernel/uv.c
> > @@ -9,6 +9,8 @@
> >  #include <linux/sizes.h>
> >  #include <linux/bitmap.h>
> >  #include <linux/memblock.h>
> > +#include <linux/pagemap.h>
> > +#include <linux/swap.h>
> >  #include <asm/facility.h>
> >  #include <asm/sections.h>
> >  #include <asm/uv.h>
> > @@ -98,4 +100,172 @@ void adjust_to_uv_max(unsigned long *vmax)
> >  	if (prot_virt_host && *vmax > uv_info.max_sec_stor_addr)
> >  		*vmax = uv_info.max_sec_stor_addr;
> >  }
> > +
> > +static int __uv_pin_shared(unsigned long paddr)
> > +{
> > +	struct uv_cb_cfs uvcb = {
> > +		.header.cmd	= UVC_CMD_PIN_PAGE_SHARED,
> > +		.header.len	= sizeof(uvcb),
> > +		.paddr		= paddr,
> > +	};
> > +
> > +	if (uv_call(0, (u64)&uvcb))
> > +		return -EINVAL;
> > +	return 0;  
> 
> I guess this call won't set an error rc in the control block, if it
> does not set a condition code != 0?

correct.
(cc == 0) ⇔ (rc == 1) which is success.
any rc other than 1 sets cc = 1





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux