KVM: do not treat noslot pfn as a error pfn
This patch filters noslot pfn out from error pfns based on Marcelo comment: noslot pfn is not a error pfn After this patch, - is_noslot_pfn indicates that the gfn is not in slot - is_error_pfn indicates that the gfn is in slot but the error is occurred when translate the gfn to pfn - is_error_noslot_pfn indicates that the pfn either it is error pfns or it is noslot pfn And is_invalid_pfn can be removed, it makes the code more clean Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
Родитель
19bf7f8ac3
Коммит
81c52c56e2
|
@ -155,7 +155,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
|
|||
|
||||
/* Get host physical address for gpa */
|
||||
hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT);
|
||||
if (is_error_pfn(hpaddr)) {
|
||||
if (is_error_noslot_pfn(hpaddr)) {
|
||||
printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n",
|
||||
orig_pte->eaddr);
|
||||
r = -EINVAL;
|
||||
|
|
|
@ -93,7 +93,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
|
|||
|
||||
/* Get host physical address for gpa */
|
||||
hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT);
|
||||
if (is_error_pfn(hpaddr)) {
|
||||
if (is_error_noslot_pfn(hpaddr)) {
|
||||
printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", orig_pte->eaddr);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
|
|
|
@ -524,7 +524,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
|
|||
if (likely(!pfnmap)) {
|
||||
unsigned long tsize_pages = 1 << (tsize + 10 - PAGE_SHIFT);
|
||||
pfn = gfn_to_pfn_memslot(slot, gfn);
|
||||
if (is_error_pfn(pfn)) {
|
||||
if (is_error_noslot_pfn(pfn)) {
|
||||
printk(KERN_ERR "Couldn't get real page for gfn %lx!\n",
|
||||
(long)gfn);
|
||||
return;
|
||||
|
|
|
@ -2699,7 +2699,7 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu,
|
|||
* PT_PAGE_TABLE_LEVEL and there would be no adjustment done
|
||||
* here.
|
||||
*/
|
||||
if (!is_error_pfn(pfn) && !kvm_is_mmio_pfn(pfn) &&
|
||||
if (!is_error_noslot_pfn(pfn) && !kvm_is_mmio_pfn(pfn) &&
|
||||
level == PT_PAGE_TABLE_LEVEL &&
|
||||
PageTransCompound(pfn_to_page(pfn)) &&
|
||||
!has_wrprotected_page(vcpu->kvm, gfn, PT_DIRECTORY_LEVEL)) {
|
||||
|
@ -2733,7 +2733,7 @@ static bool handle_abnormal_pfn(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
|
|||
bool ret = true;
|
||||
|
||||
/* The pfn is invalid, report the error! */
|
||||
if (unlikely(is_invalid_pfn(pfn))) {
|
||||
if (unlikely(is_error_pfn(pfn))) {
|
||||
*ret_val = kvm_handle_bad_page(vcpu, gfn, pfn);
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
|
|||
protect_clean_gpte(&pte_access, gpte);
|
||||
pfn = pte_prefetch_gfn_to_pfn(vcpu, gfn,
|
||||
no_dirty_log && (pte_access & ACC_WRITE_MASK));
|
||||
if (is_invalid_pfn(pfn))
|
||||
if (is_error_pfn(pfn))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
|
@ -4504,7 +4504,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
|
|||
* instruction -> ...
|
||||
*/
|
||||
pfn = gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa));
|
||||
if (!is_error_pfn(pfn)) {
|
||||
if (!is_error_noslot_pfn(pfn)) {
|
||||
kvm_release_pfn_clean(pfn);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -58,28 +58,40 @@
|
|||
|
||||
/*
|
||||
* For the normal pfn, the highest 12 bits should be zero,
|
||||
* so we can mask these bits to indicate the error.
|
||||
* so we can mask bit 62 ~ bit 52 to indicate the error pfn,
|
||||
* mask bit 63 to indicate the noslot pfn.
|
||||
*/
|
||||
#define KVM_PFN_ERR_MASK (0xfffULL << 52)
|
||||
#define KVM_PFN_ERR_MASK (0x7ffULL << 52)
|
||||
#define KVM_PFN_ERR_NOSLOT_MASK (0xfffULL << 52)
|
||||
#define KVM_PFN_NOSLOT (0x1ULL << 63)
|
||||
|
||||
#define KVM_PFN_ERR_FAULT (KVM_PFN_ERR_MASK)
|
||||
#define KVM_PFN_ERR_HWPOISON (KVM_PFN_ERR_MASK + 1)
|
||||
#define KVM_PFN_ERR_BAD (KVM_PFN_ERR_MASK + 2)
|
||||
#define KVM_PFN_ERR_RO_FAULT (KVM_PFN_ERR_MASK + 3)
|
||||
#define KVM_PFN_ERR_RO_FAULT (KVM_PFN_ERR_MASK + 2)
|
||||
|
||||
/*
|
||||
* error pfns indicate that the gfn is in slot but faild to
|
||||
* translate it to pfn on host.
|
||||
*/
|
||||
static inline bool is_error_pfn(pfn_t pfn)
|
||||
{
|
||||
return !!(pfn & KVM_PFN_ERR_MASK);
|
||||
}
|
||||
|
||||
static inline bool is_noslot_pfn(pfn_t pfn)
|
||||
/*
|
||||
* error_noslot pfns indicate that the gfn can not be
|
||||
* translated to pfn - it is not in slot or failed to
|
||||
* translate it to pfn.
|
||||
*/
|
||||
static inline bool is_error_noslot_pfn(pfn_t pfn)
|
||||
{
|
||||
return pfn == KVM_PFN_ERR_BAD;
|
||||
return !!(pfn & KVM_PFN_ERR_NOSLOT_MASK);
|
||||
}
|
||||
|
||||
static inline bool is_invalid_pfn(pfn_t pfn)
|
||||
/* noslot pfn indicates that the gfn is not in slot. */
|
||||
static inline bool is_noslot_pfn(pfn_t pfn)
|
||||
{
|
||||
return !is_noslot_pfn(pfn) && is_error_pfn(pfn);
|
||||
return pfn == KVM_PFN_NOSLOT;
|
||||
}
|
||||
|
||||
#define KVM_HVA_ERR_BAD (PAGE_OFFSET)
|
||||
|
|
|
@ -52,7 +52,7 @@ static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
|
|||
end_gfn = gfn + (size >> PAGE_SHIFT);
|
||||
gfn += 1;
|
||||
|
||||
if (is_error_pfn(pfn))
|
||||
if (is_error_noslot_pfn(pfn))
|
||||
return pfn;
|
||||
|
||||
while (gfn < end_gfn)
|
||||
|
@ -106,7 +106,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
|
|||
* important because we unmap and unpin in 4kb steps later.
|
||||
*/
|
||||
pfn = kvm_pin_pages(slot, gfn, page_size);
|
||||
if (is_error_pfn(pfn)) {
|
||||
if (is_error_noslot_pfn(pfn)) {
|
||||
gfn += 1;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1208,7 +1208,7 @@ __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn, bool atomic,
|
|||
return KVM_PFN_ERR_RO_FAULT;
|
||||
|
||||
if (kvm_is_error_hva(addr))
|
||||
return KVM_PFN_ERR_BAD;
|
||||
return KVM_PFN_NOSLOT;
|
||||
|
||||
/* Do not map writable pfn in the readonly memslot. */
|
||||
if (writable && memslot_is_readonly(slot)) {
|
||||
|
@ -1290,7 +1290,7 @@ EXPORT_SYMBOL_GPL(gfn_to_page_many_atomic);
|
|||
|
||||
static struct page *kvm_pfn_to_page(pfn_t pfn)
|
||||
{
|
||||
if (is_error_pfn(pfn))
|
||||
if (is_error_noslot_pfn(pfn))
|
||||
return KVM_ERR_PTR_BAD_PAGE;
|
||||
|
||||
if (kvm_is_mmio_pfn(pfn)) {
|
||||
|
@ -1322,7 +1322,7 @@ EXPORT_SYMBOL_GPL(kvm_release_page_clean);
|
|||
|
||||
void kvm_release_pfn_clean(pfn_t pfn)
|
||||
{
|
||||
if (!is_error_pfn(pfn) && !kvm_is_mmio_pfn(pfn))
|
||||
if (!is_error_noslot_pfn(pfn) && !kvm_is_mmio_pfn(pfn))
|
||||
put_page(pfn_to_page(pfn));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);
|
||||
|
|
Загрузка…
Ссылка в новой задаче