aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2018-01-11 15:08:32 +1100
committerDavid Gibson <david@gibson.dropbear.id.au>2018-01-17 09:35:24 +1100
commita36593e16757e524c1596d93914155bd8acbb90a (patch)
treed2c03b54991a01c7451122d3ab9cd4992132c73b /target
parent8e5dc9ba49743b46d955ec7dacb04e42ae7ada7c (diff)
target/ppc: Yet another fix for KVM-HV HPTE accessors
As stated in the 1ad9f0a464fe commit log, the returned entries are not a whole PTEG. It was not a problem before 1ad9f0a464fe as it would read a single record assuming it contains a whole PTEG but now the code tries reading the entire PTEG and "if ((n - i) < invalid)" produces negative values which then are converted to size_t for memset() and that throws seg fault. This fixes the math. While here, fix the last @i increment as well. Fixes: 1ad9f0a464fe "target/ppc: Fix KVM-HV HPTE accessors" Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/kvm.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4664a3ce9d..09fcb082d2 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2667,21 +2667,24 @@ void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n)
hdr = (struct kvm_get_htab_header *)buf;
while ((i < n) && ((char *)hdr < (buf + rc))) {
- int invalid = hdr->n_invalid;
+ int invalid = hdr->n_invalid, valid = hdr->n_valid;
if (hdr->index != (ptex + i)) {
hw_error("kvmppc_read_hptes: Unexpected HPTE index %"PRIu32
" != (%"HWADDR_PRIu" + %d", hdr->index, ptex, i);
}
- memcpy(hptes + i, hdr + 1, HASH_PTE_SIZE_64 * hdr->n_valid);
- i += hdr->n_valid;
+ if (n - i < valid) {
+ valid = n - i;
+ }
+ memcpy(hptes + i, hdr + 1, HASH_PTE_SIZE_64 * valid);
+ i += valid;
if ((n - i) < invalid) {
invalid = n - i;
}
memset(hptes + i, 0, invalid * HASH_PTE_SIZE_64);
- i += hdr->n_invalid;
+ i += invalid;
hdr = (struct kvm_get_htab_header *)
((char *)(hdr + 1) + HASH_PTE_SIZE_64 * hdr->n_valid);