mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-07 03:18:31 +00:00
KVM: PPC: Book3S PR: Disallow AIL != 0
KVM PR does not implement address translation modes on interrupt, so it must not allow H_SET_MODE to succeed. The behaviour change caused by this mode is architected and not advisory (interrupts *must* behave differently). QEMU does not deal with differences in AIL support in the host. The solution to that is a spapr capability and corresponding KVM CAP, but this patch does not break things more than before (the host behaviour already differs, this change just disallows some modes that are not implemented properly). By happy coincidence, this allows PR Linux guests that are using the SCV facility to boot and run, because Linux disables the use of SCV if AIL can not be set to 3. This does not fix the underlying problem of missing SCV support (an OS could implement real-mode SCV vectors and try to enable the facility). The true fix for that is for KVM PR to emulate scv interrupts from the facility unavailable interrupt. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com> Link: https://lore.kernel.org/r/20220222064727.2314380-3-npiggin@gmail.com
This commit is contained in:
parent
b5149e2292
commit
839d893b40
1 changed files with 20 additions and 0 deletions
|
@ -281,6 +281,22 @@ static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu *vcpu)
|
||||||
return EMULATE_DONE;
|
return EMULATE_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kvmppc_h_pr_set_mode(struct kvm_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
unsigned long mflags = kvmppc_get_gpr(vcpu, 4);
|
||||||
|
unsigned long resource = kvmppc_get_gpr(vcpu, 5);
|
||||||
|
|
||||||
|
if (resource == H_SET_MODE_RESOURCE_ADDR_TRANS_MODE) {
|
||||||
|
/* KVM PR does not provide AIL!=0 to guests */
|
||||||
|
if (mflags == 0)
|
||||||
|
kvmppc_set_gpr(vcpu, 3, H_SUCCESS);
|
||||||
|
else
|
||||||
|
kvmppc_set_gpr(vcpu, 3, H_UNSUPPORTED_FLAG_START - 63);
|
||||||
|
return EMULATE_DONE;
|
||||||
|
}
|
||||||
|
return EMULATE_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SPAPR_TCE_IOMMU
|
#ifdef CONFIG_SPAPR_TCE_IOMMU
|
||||||
static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
|
static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
|
@ -384,6 +400,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
|
||||||
return kvmppc_h_pr_logical_ci_load(vcpu);
|
return kvmppc_h_pr_logical_ci_load(vcpu);
|
||||||
case H_LOGICAL_CI_STORE:
|
case H_LOGICAL_CI_STORE:
|
||||||
return kvmppc_h_pr_logical_ci_store(vcpu);
|
return kvmppc_h_pr_logical_ci_store(vcpu);
|
||||||
|
case H_SET_MODE:
|
||||||
|
return kvmppc_h_pr_set_mode(vcpu);
|
||||||
case H_XIRR:
|
case H_XIRR:
|
||||||
case H_CPPR:
|
case H_CPPR:
|
||||||
case H_EOI:
|
case H_EOI:
|
||||||
|
@ -421,6 +439,7 @@ int kvmppc_hcall_impl_pr(unsigned long cmd)
|
||||||
case H_CEDE:
|
case H_CEDE:
|
||||||
case H_LOGICAL_CI_LOAD:
|
case H_LOGICAL_CI_LOAD:
|
||||||
case H_LOGICAL_CI_STORE:
|
case H_LOGICAL_CI_STORE:
|
||||||
|
case H_SET_MODE:
|
||||||
#ifdef CONFIG_KVM_XICS
|
#ifdef CONFIG_KVM_XICS
|
||||||
case H_XIRR:
|
case H_XIRR:
|
||||||
case H_CPPR:
|
case H_CPPR:
|
||||||
|
@ -447,6 +466,7 @@ static unsigned int default_hcall_list[] = {
|
||||||
H_BULK_REMOVE,
|
H_BULK_REMOVE,
|
||||||
H_PUT_TCE,
|
H_PUT_TCE,
|
||||||
H_CEDE,
|
H_CEDE,
|
||||||
|
H_SET_MODE,
|
||||||
#ifdef CONFIG_KVM_XICS
|
#ifdef CONFIG_KVM_XICS
|
||||||
H_XIRR,
|
H_XIRR,
|
||||||
H_CPPR,
|
H_CPPR,
|
||||||
|
|
Loading…
Reference in a new issue