KVM: S390: Create helper function get_guest_storage_key
Define get_guest_storage_key which can be used to get the value of a guest storage key. This compliments the functionality provided by the helper function set_guest_storage_key. Both functions are needed for live migration of s390 guests that use storage keys. Signed-off-by: Jason J. Herne <jjherne@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
da00fcbdac
commit
9fcf93b5de
@ -26,6 +26,7 @@ void page_table_reset_pgste(struct mm_struct *, unsigned long, unsigned long,
|
||||
bool init_skey);
|
||||
int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
|
||||
unsigned long key, bool nq);
|
||||
unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr);
|
||||
|
||||
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
|
||||
{
|
||||
|
@ -980,6 +980,45 @@ retry:
|
||||
}
|
||||
EXPORT_SYMBOL(set_guest_storage_key);
|
||||
|
||||
unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
spinlock_t *ptl;
|
||||
pgste_t pgste;
|
||||
pte_t *ptep;
|
||||
uint64_t physaddr;
|
||||
unsigned long key = 0;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
ptep = get_locked_pte(mm, addr, &ptl);
|
||||
if (unlikely(!ptep)) {
|
||||
up_read(&mm->mmap_sem);
|
||||
return -EFAULT;
|
||||
}
|
||||
pgste = pgste_get_lock(ptep);
|
||||
|
||||
if (pte_val(*ptep) & _PAGE_INVALID) {
|
||||
key |= (pgste_val(pgste) & PGSTE_ACC_BITS) >> 56;
|
||||
key |= (pgste_val(pgste) & PGSTE_FP_BIT) >> 56;
|
||||
key |= (pgste_val(pgste) & PGSTE_GR_BIT) >> 48;
|
||||
key |= (pgste_val(pgste) & PGSTE_GC_BIT) >> 48;
|
||||
} else {
|
||||
physaddr = pte_val(*ptep) & PAGE_MASK;
|
||||
key = page_get_storage_key(physaddr);
|
||||
|
||||
/* Reflect guest's logical view, not physical */
|
||||
if (pgste_val(pgste) & PGSTE_GR_BIT)
|
||||
key |= _PAGE_REFERENCED;
|
||||
if (pgste_val(pgste) & PGSTE_GC_BIT)
|
||||
key |= _PAGE_CHANGED;
|
||||
}
|
||||
|
||||
pgste_set_unlock(ptep, pgste);
|
||||
pte_unmap_unlock(ptep, ptl);
|
||||
up_read(&mm->mmap_sem);
|
||||
return key;
|
||||
}
|
||||
EXPORT_SYMBOL(get_guest_storage_key);
|
||||
|
||||
#else /* CONFIG_PGSTE */
|
||||
|
||||
static inline int page_table_with_pgste(struct page *page)
|
||||
|
Loading…
Reference in New Issue
Block a user