Skip to content

Commit 071790e

Browse files
committed
Get the right physical address from MDL directly.
This fixes a random runtime hang when working set is trimmed.
1 parent 5d157d1 commit 071790e

1 file changed

Lines changed: 13 additions & 47 deletions

File tree

virt/kvm/kvm_main.c

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,50 +1221,6 @@ size_t kvm_vcpu_gfn_to_hva_prot(struct kvm_vcpu *vcpu, gfn_t gfn, bool *writable
12211221
return gfn_to_hva_memslot_prot(slot, gfn, writable);
12221222
}
12231223

1224-
/*
1225-
* The atomic path to get the writable pfn which will be stored in @pfn,
1226-
* true indicates success, otherwise false is returned.
1227-
*/
1228-
static bool __hva_to_pfn(size_t addr,
1229-
bool write_fault, bool *writable, kvm_pfn_t *pfn)
1230-
{
1231-
if (writable)
1232-
*writable = write_fault;
1233-
1234-
/* map read fault as writable if possible */
1235-
if (!write_fault && writable)
1236-
*writable = true;
1237-
1238-
*pfn = __pa((void *)addr) >> PAGE_SHIFT;
1239-
1240-
return true;
1241-
}
1242-
1243-
/*
1244-
* Pin guest page in memory and return its pfn.
1245-
* @addr: host virtual address which maps memory to the guest
1246-
* @atomic: whether this function can sleep
1247-
* @async: whether this function need to wait IO complete if the
1248-
* host page is not in the memory
1249-
* @write_fault: whether we should get a writable host page
1250-
* @writable: whether it allows to map a writable host page for !@write_fault
1251-
*
1252-
* The function will map a writable host page for these two cases:
1253-
* 1): @write_fault = true
1254-
* 2): @write_fault = false && @writable, @writable will tell the caller
1255-
* whether the mapping is writable.
1256-
*/
1257-
static kvm_pfn_t hva_to_pfn(size_t addr,
1258-
bool write_fault, bool *writable)
1259-
{
1260-
kvm_pfn_t pfn = 0;
1261-
1262-
if (__hva_to_pfn(addr, write_fault, writable, &pfn))
1263-
return pfn;
1264-
1265-
return GVM_PFN_ERR_FAULT;
1266-
}
1267-
12681224
static int gvm_pin_user_memory(size_t addr, struct pmem_lock *pmem_lock)
12691225
{
12701226
pmem_lock->lock_mdl = IoAllocateMdl((PVOID)addr, PAGE_SIZE,
@@ -1274,6 +1230,7 @@ static int gvm_pin_user_memory(size_t addr, struct pmem_lock *pmem_lock)
12741230
if (!__MmProbeAndLockPages(pmem_lock->lock_mdl, UserMode,
12751231
IoWriteAccess)) {
12761232
IoFreeMdl(pmem_lock->lock_mdl);
1233+
pmem_lock->lock_mdl = NULL;
12771234
return -1;
12781235
}
12791236
return 0;
@@ -1318,7 +1275,14 @@ kvm_pfn_t __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn,
13181275
}
13191276
spin_unlock(&pmem_lock->lock);
13201277

1321-
return hva_to_pfn(addr, write_fault, writable);
1278+
if (writable)
1279+
*writable = write_fault;
1280+
1281+
/* map read fault as writable if possible */
1282+
if (!write_fault && writable)
1283+
*writable = true;
1284+
1285+
return MmGetMdlPfnArray(pmem_lock->lock_mdl)[0];
13221286
}
13231287

13241288
kvm_pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
@@ -1388,8 +1352,10 @@ int gfn_to_pfn_many_atomic(struct kvm_memory_slot *slot, gfn_t gfn,
13881352

13891353
nr_pages = i;
13901354

1391-
while(i--)
1392-
pfn[i] = __pa((void*)(addr + i * PAGE_SIZE)) >> PAGE_SHIFT;
1355+
while(i--) {
1356+
pmem_lock = &slot->pmem_lock[gfn + i - slot->base_gfn];
1357+
pfn[i] = MmGetMdlPfnArray(pmem_lock->lock_mdl)[0];
1358+
}
13931359
return nr_pages;
13941360
}
13951361

0 commit comments

Comments
 (0)