This adds an array that parallels the guest hashed page table (HPT), that is, it has one entry per HPTE, used to store the guest's view of the second doubleword of the corresponding HPTE. The first doubleword in the HPTE is the same as the guest's idea of it, so we don't need to store a copy, but the second doubleword in the HPTE has the real page number rather than the guest's logical page number. This allows us to remove the back_translate() and reverse_xlate() functions. This "reverse mapping" array is vmalloc'd, meaning that to access it in real mode we have to walk the kernel's page tables explicitly. That is done by the new real_vmalloc_addr() function. (In fact this returns an address in the linear mapping, so the result is usable both in real mode and in virtual mode.) There are also some minor cleanups here: moving the definitions of HPT_ORDER etc. to a header file and defining HPT_NPTE for HPT_NPTEG << 3. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
80 lines
2.3 KiB
C
80 lines
2.3 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License, version 2, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright SUSE Linux Products GmbH 2010
|
|
*
|
|
* Authors: Alexander Graf <agraf@suse.de>
|
|
*/
|
|
|
|
#ifndef __ASM_KVM_BOOK3S_64_H__
|
|
#define __ASM_KVM_BOOK3S_64_H__
|
|
|
|
#ifdef CONFIG_KVM_BOOK3S_PR
|
|
static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu)
|
|
{
|
|
preempt_disable();
|
|
return &get_paca()->shadow_vcpu;
|
|
}
|
|
|
|
static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)
|
|
{
|
|
preempt_enable();
|
|
}
|
|
#endif
|
|
|
|
#define SPAPR_TCE_SHIFT 12
|
|
|
|
#ifdef CONFIG_KVM_BOOK3S_64_HV
|
|
/* For now use fixed-size 16MB page table */
|
|
#define HPT_ORDER 24
|
|
#define HPT_NPTEG (1ul << (HPT_ORDER - 7)) /* 128B per pteg */
|
|
#define HPT_NPTE (HPT_NPTEG << 3) /* 8 PTEs per PTEG */
|
|
#define HPT_HASH_MASK (HPT_NPTEG - 1)
|
|
#endif
|
|
|
|
static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
|
|
unsigned long pte_index)
|
|
{
|
|
unsigned long rb, va_low;
|
|
|
|
rb = (v & ~0x7fUL) << 16; /* AVA field */
|
|
va_low = pte_index >> 3;
|
|
if (v & HPTE_V_SECONDARY)
|
|
va_low = ~va_low;
|
|
/* xor vsid from AVA */
|
|
if (!(v & HPTE_V_1TB_SEG))
|
|
va_low ^= v >> 12;
|
|
else
|
|
va_low ^= v >> 24;
|
|
va_low &= 0x7ff;
|
|
if (v & HPTE_V_LARGE) {
|
|
rb |= 1; /* L field */
|
|
if (cpu_has_feature(CPU_FTR_ARCH_206) &&
|
|
(r & 0xff000)) {
|
|
/* non-16MB large page, must be 64k */
|
|
/* (masks depend on page size) */
|
|
rb |= 0x1000; /* page encoding in LP field */
|
|
rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */
|
|
rb |= (va_low & 0xfe); /* AVAL field (P7 doesn't seem to care) */
|
|
}
|
|
} else {
|
|
/* 4kB page */
|
|
rb |= (va_low & 0x7ff) << 12; /* remaining 11b of VA */
|
|
}
|
|
rb |= (v >> 54) & 0x300; /* B field */
|
|
return rb;
|
|
}
|
|
|
|
#endif /* __ASM_KVM_BOOK3S_64_H__ */
|