]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
KVM: s390: Add storage key facility interpretation control
authorJanosch Frank <frankja@linux.vnet.ibm.com>
Thu, 15 Feb 2018 15:33:47 +0000 (16:33 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 17 May 2018 07:00:41 +0000 (09:00 +0200)
Up to now we always expected to have the storage key facility
available for our (non-VSIE) KVM guests. For huge page support, we
need to be able to disable it, so let's introduce that now.

We add the use_skf variable to manage KVM storage key facility
usage. Also we rename use_skey in the mm context struct to uses_skeys
to make it more clear that it is an indication that the vm actively
uses storage keys.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/include/asm/kvm_host.h
arch/s390/include/asm/mmu.h
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/pgtable.h
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/priv.c
arch/s390/mm/gmap.c
arch/s390/mm/pgtable.c

index 81cdb6b5511840ae39721c24ea386ed881670011..a2188e309bd6faedb524510198ec9671e20494cf 100644 (file)
@@ -812,6 +812,7 @@ struct kvm_arch{
        int use_irqchip;
        int use_cmma;
        int use_pfmfi;
+       int use_skf;
        int user_cpu_state_ctrl;
        int user_sigp;
        int user_stsi;
index c639c95850e469de3f834d93d3b66317d7d8a418..f5ff9dbad8ac9590a1bbdfc80979bc1c74cf8ede 100644 (file)
@@ -21,7 +21,7 @@ typedef struct {
        /* The mmu context uses extended page tables. */
        unsigned int has_pgste:1;
        /* The mmu context uses storage keys. */
-       unsigned int use_skey:1;
+       unsigned int uses_skeys:1;
        /* The mmu context uses CMM. */
        unsigned int uses_cmm:1;
 } mm_context_t;
index 324f6f452982ca9ce9844c9818943fbc0c5766cd..d16bc79c30bbfe216b4d7f662e972f60631f055f 100644 (file)
@@ -30,7 +30,7 @@ static inline int init_new_context(struct task_struct *tsk,
                test_thread_flag(TIF_PGSTE) ||
                (current->mm && current->mm->context.alloc_pgste);
        mm->context.has_pgste = 0;
-       mm->context.use_skey = 0;
+       mm->context.uses_skeys = 0;
        mm->context.uses_cmm = 0;
 #endif
        switch (mm->context.asce_limit) {
index 2d24d33bf188a0957927a6addd8a7eb38a5319f6..c9f155b67660589fe460cd83a2df886cd5503f7d 100644 (file)
@@ -507,10 +507,10 @@ static inline int mm_alloc_pgste(struct mm_struct *mm)
  * faults should no longer be backed by zero pages
  */
 #define mm_forbids_zeropage mm_has_pgste
-static inline int mm_use_skey(struct mm_struct *mm)
+static inline int mm_uses_skeys(struct mm_struct *mm)
 {
 #ifdef CONFIG_PGSTE
-       if (mm->context.use_skey)
+       if (mm->context.uses_skeys)
                return 1;
 #endif
        return 0;
index 64c9862430187b90e132ce96cb51a410c6fabff9..007db8faafa5f933b40619a8f5b83c60e947eed5 100644 (file)
@@ -1493,7 +1493,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
                return -EINVAL;
 
        /* Is this guest using storage keys? */
-       if (!mm_use_skey(current->mm))
+       if (!mm_uses_skeys(current->mm))
                return KVM_S390_GET_SKEYS_NONE;
 
        /* Enforce sane limit on memory allocation */
@@ -2066,6 +2066,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        kvm->arch.css_support = 0;
        kvm->arch.use_irqchip = 0;
        kvm->arch.use_pfmfi = sclp.has_pfmfi;
+       kvm->arch.use_skf = sclp.has_skey;
        kvm->arch.epoch = 0;
 
        spin_lock_init(&kvm->arch.start_stop_lock);
index ebfa0442e569af65fae1a46a4736024555721b80..e8c62703c76452003a9c30ec8d893cb43437ba9f 100644 (file)
@@ -205,24 +205,28 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
 
 int kvm_s390_skey_check_enable(struct kvm_vcpu *vcpu)
 {
-       int rc = 0;
+       int rc;
        struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
 
        trace_kvm_s390_skey_related_inst(vcpu);
-       if (!(sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE)) &&
+       /* Already enabled? */
+       if (vcpu->kvm->arch.use_skf &&
+           !(sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE)) &&
            !kvm_s390_test_cpuflags(vcpu, CPUSTAT_KSS))
-               return rc;
+               return 0;
 
        rc = s390_enable_skey();
        VCPU_EVENT(vcpu, 3, "enabling storage keys for guest: %d", rc);
-       if (!rc) {
-               if (kvm_s390_test_cpuflags(vcpu, CPUSTAT_KSS))
-                       kvm_s390_clear_cpuflags(vcpu, CPUSTAT_KSS);
-               else
-                       sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE |
-                                            ICTL_RRBE);
-       }
-       return rc;
+       if (rc)
+               return rc;
+
+       if (kvm_s390_test_cpuflags(vcpu, CPUSTAT_KSS))
+               kvm_s390_clear_cpuflags(vcpu, CPUSTAT_KSS);
+       if (!vcpu->kvm->arch.use_skf)
+               sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE;
+       else
+               sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE | ICTL_RRBE);
+       return 0;
 }
 
 static int try_handle_skey(struct kvm_vcpu *vcpu)
@@ -232,7 +236,7 @@ static int try_handle_skey(struct kvm_vcpu *vcpu)
        rc = kvm_s390_skey_check_enable(vcpu);
        if (rc)
                return rc;
-       if (sclp.has_skey) {
+       if (vcpu->kvm->arch.use_skf) {
                /* with storage-key facility, SIE interprets it for us */
                kvm_s390_retry_instr(vcpu);
                VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation");
index 2c55a2b9d6c65bde78efacf77c71826001b3d4b1..bc56ec8abcf7f7ec680568908e05d0de3fd303e4 100644 (file)
@@ -2184,14 +2184,14 @@ int s390_enable_skey(void)
        int rc = 0;
 
        down_write(&mm->mmap_sem);
-       if (mm_use_skey(mm))
+       if (mm_uses_skeys(mm))
                goto out_up;
 
-       mm->context.use_skey = 1;
+       mm->context.uses_skeys = 1;
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
                                MADV_UNMERGEABLE, &vma->vm_flags)) {
-                       mm->context.use_skey = 0;
+                       mm->context.uses_skeys = 0;
                        rc = -ENOMEM;
                        goto out_up;
                }
index 4f2b65d01a70418c802d6ce33713101ec0e2909b..301e466e4263d8c87abd9069952c10dac371f640 100644 (file)
@@ -158,7 +158,7 @@ static inline pgste_t pgste_update_all(pte_t pte, pgste_t pgste,
 #ifdef CONFIG_PGSTE
        unsigned long address, bits, skey;
 
-       if (!mm_use_skey(mm) || pte_val(pte) & _PAGE_INVALID)
+       if (!mm_uses_skeys(mm) || pte_val(pte) & _PAGE_INVALID)
                return pgste;
        address = pte_val(pte) & PAGE_MASK;
        skey = (unsigned long) page_get_storage_key(address);
@@ -180,7 +180,7 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry,
        unsigned long address;
        unsigned long nkey;
 
-       if (!mm_use_skey(mm) || pte_val(entry) & _PAGE_INVALID)
+       if (!mm_uses_skeys(mm) || pte_val(entry) & _PAGE_INVALID)
                return;
        VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID));
        address = pte_val(entry) & PAGE_MASK;