powerpc/papr_scm: Use the correct bind address
When binding an SCM volume to a physical address the hypervisor has the
option to return early with a continue token with the expectation that
the guest will resume the bind operation until it completes. A quirk of
this interface is that the bind address will only be returned by the
first bind h-call and the subsequent calls will return
0xFFFF_FFFF_FFFF_FFFF for the bind address.
We currently do not save the address returned by the first h-call. As a
result we will use the junk address as the base of the bound region if
the hypervisor decides to split the bind across multiple h-calls. This
bug was found when testing with very large SCM volumes where the bind
process would take more time than they hypervisor's internal h-call time
limit would allow. This patch fixes the issue by saving the bind address
from the first call.
Cc: stable@vger.kernel.org
Fixes: b5beae5e22
("powerpc/pseries: Add driver for PAPR SCM regions")
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
579b9239c1
commit
5a3840a470
@ -43,6 +43,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
|
|||||||
{
|
{
|
||||||
unsigned long ret[PLPAR_HCALL_BUFSIZE];
|
unsigned long ret[PLPAR_HCALL_BUFSIZE];
|
||||||
uint64_t rc, token;
|
uint64_t rc, token;
|
||||||
|
uint64_t saved = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the hypervisor cannot map all the requested memory in a single
|
* When the hypervisor cannot map all the requested memory in a single
|
||||||
@ -56,6 +57,8 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
|
|||||||
rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0,
|
rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0,
|
||||||
p->blocks, BIND_ANY_ADDR, token);
|
p->blocks, BIND_ANY_ADDR, token);
|
||||||
token = ret[0];
|
token = ret[0];
|
||||||
|
if (!saved)
|
||||||
|
saved = ret[1];
|
||||||
cond_resched();
|
cond_resched();
|
||||||
} while (rc == H_BUSY);
|
} while (rc == H_BUSY);
|
||||||
|
|
||||||
@ -64,7 +67,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
|
|||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->bound_addr = ret[1];
|
p->bound_addr = saved;
|
||||||
|
|
||||||
dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res);
|
dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user