Merge branch 'topic/ppc-kvm' into next
Merge some more commits from our KVM topic branch. In particular this brings in some commits that depend on a new capability that was merged via the KVM tree for v5.18.
This commit is contained in:
@@ -28,11 +28,13 @@ void setup_panic(void);
|
|||||||
#define ARCH_PANIC_TIMEOUT 180
|
#define ARCH_PANIC_TIMEOUT 180
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
|
extern bool pseries_reloc_on_exception(void);
|
||||||
extern bool pseries_enable_reloc_on_exc(void);
|
extern bool pseries_enable_reloc_on_exc(void);
|
||||||
extern void pseries_disable_reloc_on_exc(void);
|
extern void pseries_disable_reloc_on_exc(void);
|
||||||
extern void pseries_big_endian_exceptions(void);
|
extern void pseries_big_endian_exceptions(void);
|
||||||
void __init pseries_little_endian_exceptions(void);
|
void __init pseries_little_endian_exceptions(void);
|
||||||
#else
|
#else
|
||||||
|
static inline bool pseries_reloc_on_exception(void) { return false; }
|
||||||
static inline bool pseries_enable_reloc_on_exc(void) { return false; }
|
static inline bool pseries_enable_reloc_on_exc(void) { return false; }
|
||||||
static inline void pseries_disable_reloc_on_exc(void) {}
|
static inline void pseries_disable_reloc_on_exc(void) {}
|
||||||
static inline void pseries_big_endian_exceptions(void) {}
|
static inline void pseries_big_endian_exceptions(void) {}
|
||||||
|
|||||||
@@ -809,6 +809,10 @@ __start_interrupts:
|
|||||||
* - MSR_EE|MSR_RI is clear (no reentrant exceptions)
|
* - MSR_EE|MSR_RI is clear (no reentrant exceptions)
|
||||||
* - Standard kernel environment is set up (stack, paca, etc)
|
* - Standard kernel environment is set up (stack, paca, etc)
|
||||||
*
|
*
|
||||||
|
* KVM:
|
||||||
|
* These interrupts do not elevate HV 0->1, so HV is not involved. PR KVM
|
||||||
|
* ensures that FSCR[SCV] is disabled whenever it has to force AIL off.
|
||||||
|
*
|
||||||
* Call convention:
|
* Call convention:
|
||||||
*
|
*
|
||||||
* syscall register convention is in Documentation/powerpc/syscall64-abi.rst
|
* syscall register convention is in Documentation/powerpc/syscall64-abi.rst
|
||||||
|
|||||||
@@ -196,6 +196,34 @@ static void __init configure_exceptions(void)
|
|||||||
|
|
||||||
/* Under a PAPR hypervisor, we need hypercalls */
|
/* Under a PAPR hypervisor, we need hypercalls */
|
||||||
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
|
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
|
||||||
|
/*
|
||||||
|
* - PR KVM does not support AIL mode interrupts in the host
|
||||||
|
* while a PR guest is running.
|
||||||
|
*
|
||||||
|
* - SCV system call interrupt vectors are only implemented for
|
||||||
|
* AIL mode interrupts.
|
||||||
|
*
|
||||||
|
* - On pseries, AIL mode can only be enabled and disabled
|
||||||
|
* system-wide so when a PR VM is created on a pseries host,
|
||||||
|
* all CPUs of the host are set to AIL=0 mode.
|
||||||
|
*
|
||||||
|
* - Therefore host CPUs must not execute scv while a PR VM
|
||||||
|
* exists.
|
||||||
|
*
|
||||||
|
* - SCV support can not be disabled dynamically because the
|
||||||
|
* feature is advertised to host userspace. Disabling the
|
||||||
|
* facility and emulating it would be possible but is not
|
||||||
|
* implemented.
|
||||||
|
*
|
||||||
|
* - So SCV support is blanket disabled if PR KVM could possibly
|
||||||
|
* run. That is, PR support compiled in, booting on pseries
|
||||||
|
* with hash MMU.
|
||||||
|
*/
|
||||||
|
if (IS_ENABLED(CONFIG_KVM_BOOK3S_PR_POSSIBLE) && !radix_enabled()) {
|
||||||
|
init_task.thread.fscr &= ~FSCR_SCV;
|
||||||
|
cur_cpu_spec->cpu_user_features2 &= ~PPC_FEATURE2_SCV;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable AIL if possible */
|
/* Enable AIL if possible */
|
||||||
if (!pseries_enable_reloc_on_exc()) {
|
if (!pseries_enable_reloc_on_exc()) {
|
||||||
init_task.thread.fscr &= ~FSCR_SCV;
|
init_task.thread.fscr &= ~FSCR_SCV;
|
||||||
|
|||||||
@@ -112,12 +112,21 @@ config KVM_BOOK3S_64_PR
|
|||||||
guest in user mode (problem state) and emulating all
|
guest in user mode (problem state) and emulating all
|
||||||
privileged instructions and registers.
|
privileged instructions and registers.
|
||||||
|
|
||||||
|
This is only available for hash MMU mode and only supports
|
||||||
|
guests that use hash MMU mode.
|
||||||
|
|
||||||
This is not as fast as using hypervisor mode, but works on
|
This is not as fast as using hypervisor mode, but works on
|
||||||
machines where hypervisor mode is not available or not usable,
|
machines where hypervisor mode is not available or not usable,
|
||||||
and can emulate processors that are different from the host
|
and can emulate processors that are different from the host
|
||||||
processor, including emulating 32-bit processors on a 64-bit
|
processor, including emulating 32-bit processors on a 64-bit
|
||||||
host.
|
host.
|
||||||
|
|
||||||
|
Selecting this option will cause the SCV facility to be
|
||||||
|
disabled when the kernel is booted on the pseries platform in
|
||||||
|
hash MMU mode (regardless of PR VMs running). When any PR VMs
|
||||||
|
are running, "AIL" mode is disabled which may slow interrupts
|
||||||
|
and system calls on the host.
|
||||||
|
|
||||||
config KVM_BOOK3S_HV_EXIT_TIMING
|
config KVM_BOOK3S_HV_EXIT_TIMING
|
||||||
bool "Detailed timing for hypervisor real-mode code"
|
bool "Detailed timing for hypervisor real-mode code"
|
||||||
depends on KVM_BOOK3S_HV_POSSIBLE && DEBUG_FS
|
depends on KVM_BOOK3S_HV_POSSIBLE && DEBUG_FS
|
||||||
|
|||||||
@@ -225,6 +225,13 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
|
|||||||
int cpu;
|
int cpu;
|
||||||
struct rcuwait *waitp;
|
struct rcuwait *waitp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rcuwait_wake_up contains smp_mb() which orders prior stores that
|
||||||
|
* create pending work vs below loads of cpu fields. The other side
|
||||||
|
* is the barrier in vcpu run that orders setting the cpu fields vs
|
||||||
|
* testing for pending work.
|
||||||
|
*/
|
||||||
|
|
||||||
waitp = kvm_arch_vcpu_get_wait(vcpu);
|
waitp = kvm_arch_vcpu_get_wait(vcpu);
|
||||||
if (rcuwait_wake_up(waitp))
|
if (rcuwait_wake_up(waitp))
|
||||||
++vcpu->stat.generic.halt_wakeup;
|
++vcpu->stat.generic.halt_wakeup;
|
||||||
@@ -1089,7 +1096,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tvcpu->arch.prodded = 1;
|
tvcpu->arch.prodded = 1;
|
||||||
smp_mb();
|
smp_mb(); /* This orders prodded store vs ceded load */
|
||||||
if (tvcpu->arch.ceded)
|
if (tvcpu->arch.ceded)
|
||||||
kvmppc_fast_vcpu_kick_hv(tvcpu);
|
kvmppc_fast_vcpu_kick_hv(tvcpu);
|
||||||
break;
|
break;
|
||||||
@@ -3766,6 +3773,14 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
|
|||||||
pvc = core_info.vc[sub];
|
pvc = core_info.vc[sub];
|
||||||
pvc->pcpu = pcpu + thr;
|
pvc->pcpu = pcpu + thr;
|
||||||
for_each_runnable_thread(i, vcpu, pvc) {
|
for_each_runnable_thread(i, vcpu, pvc) {
|
||||||
|
/*
|
||||||
|
* XXX: is kvmppc_start_thread called too late here?
|
||||||
|
* It updates vcpu->cpu and vcpu->arch.thread_cpu
|
||||||
|
* which are used by kvmppc_fast_vcpu_kick_hv(), but
|
||||||
|
* kick is called after new exceptions become available
|
||||||
|
* and exceptions are checked earlier than here, by
|
||||||
|
* kvmppc_core_prepare_to_enter.
|
||||||
|
*/
|
||||||
kvmppc_start_thread(vcpu, pvc);
|
kvmppc_start_thread(vcpu, pvc);
|
||||||
kvmppc_create_dtl_entry(vcpu, pvc);
|
kvmppc_create_dtl_entry(vcpu, pvc);
|
||||||
trace_kvm_guest_enter(vcpu);
|
trace_kvm_guest_enter(vcpu);
|
||||||
@@ -4487,6 +4502,21 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||||||
if (need_resched() || !kvm->arch.mmu_ready)
|
if (need_resched() || !kvm->arch.mmu_ready)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
vcpu->cpu = pcpu;
|
||||||
|
vcpu->arch.thread_cpu = pcpu;
|
||||||
|
vc->pcpu = pcpu;
|
||||||
|
local_paca->kvm_hstate.kvm_vcpu = vcpu;
|
||||||
|
local_paca->kvm_hstate.ptid = 0;
|
||||||
|
local_paca->kvm_hstate.fake_suspend = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Orders set cpu/thread_cpu vs testing for pending interrupts and
|
||||||
|
* doorbells below. The other side is when these fields are set vs
|
||||||
|
* kvmppc_fast_vcpu_kick_hv reading the cpu/thread_cpu fields to
|
||||||
|
* kick a vCPU to notice the pending interrupt.
|
||||||
|
*/
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
if (!nested) {
|
if (!nested) {
|
||||||
kvmppc_core_prepare_to_enter(vcpu);
|
kvmppc_core_prepare_to_enter(vcpu);
|
||||||
if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
|
if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
|
||||||
@@ -4506,13 +4536,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||||||
|
|
||||||
tb = mftb();
|
tb = mftb();
|
||||||
|
|
||||||
vcpu->cpu = pcpu;
|
|
||||||
vcpu->arch.thread_cpu = pcpu;
|
|
||||||
vc->pcpu = pcpu;
|
|
||||||
local_paca->kvm_hstate.kvm_vcpu = vcpu;
|
|
||||||
local_paca->kvm_hstate.ptid = 0;
|
|
||||||
local_paca->kvm_hstate.fake_suspend = 0;
|
|
||||||
|
|
||||||
__kvmppc_create_dtl_entry(vcpu, pcpu, tb + vc->tb_offset, 0);
|
__kvmppc_create_dtl_entry(vcpu, pcpu, tb + vc->tb_offset, 0);
|
||||||
|
|
||||||
trace_kvm_guest_enter(vcpu);
|
trace_kvm_guest_enter(vcpu);
|
||||||
@@ -4614,6 +4637,8 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||||||
run->exit_reason = KVM_EXIT_INTR;
|
run->exit_reason = KVM_EXIT_INTR;
|
||||||
vcpu->arch.ret = -EINTR;
|
vcpu->arch.ret = -EINTR;
|
||||||
out:
|
out:
|
||||||
|
vcpu->cpu = -1;
|
||||||
|
vcpu->arch.thread_cpu = -1;
|
||||||
powerpc_local_irq_pmu_restore(flags);
|
powerpc_local_irq_pmu_restore(flags);
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
goto done;
|
goto done;
|
||||||
|
|||||||
@@ -137,12 +137,15 @@ static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu)
|
|||||||
svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max;
|
svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max;
|
||||||
svcpu->in_use = 0;
|
svcpu->in_use = 0;
|
||||||
svcpu_put(svcpu);
|
svcpu_put(svcpu);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable AIL if supported */
|
/* Disable AIL if supported */
|
||||||
if (cpu_has_feature(CPU_FTR_HVMODE) &&
|
if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
||||||
cpu_has_feature(CPU_FTR_ARCH_207S))
|
if (cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||||
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL);
|
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL);
|
||||||
|
if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
|
||||||
|
mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) & ~FSCR_SCV);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vcpu->cpu = smp_processor_id();
|
vcpu->cpu = smp_processor_id();
|
||||||
#ifdef CONFIG_PPC_BOOK3S_32
|
#ifdef CONFIG_PPC_BOOK3S_32
|
||||||
@@ -165,6 +168,14 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
|
|||||||
memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb));
|
memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb));
|
||||||
to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max;
|
to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max;
|
||||||
svcpu_put(svcpu);
|
svcpu_put(svcpu);
|
||||||
|
|
||||||
|
/* Enable AIL if supported */
|
||||||
|
if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
||||||
|
if (cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||||
|
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3);
|
||||||
|
if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
|
||||||
|
mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) | FSCR_SCV);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (kvmppc_is_split_real(vcpu))
|
if (kvmppc_is_split_real(vcpu))
|
||||||
@@ -174,11 +185,6 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
|
|||||||
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
|
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
|
||||||
kvmppc_save_tm_pr(vcpu);
|
kvmppc_save_tm_pr(vcpu);
|
||||||
|
|
||||||
/* Enable AIL if supported */
|
|
||||||
if (cpu_has_feature(CPU_FTR_HVMODE) &&
|
|
||||||
cpu_has_feature(CPU_FTR_ARCH_207S))
|
|
||||||
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3);
|
|
||||||
|
|
||||||
vcpu->cpu = -1;
|
vcpu->cpu = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,6 +1043,8 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)
|
|||||||
|
|
||||||
void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr)
|
void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr)
|
||||||
{
|
{
|
||||||
|
if (fscr & FSCR_SCV)
|
||||||
|
fscr &= ~FSCR_SCV; /* SCV must not be enabled */
|
||||||
if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) {
|
if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) {
|
||||||
/* TAR got dropped, drop it in shadow too */
|
/* TAR got dropped, drop it in shadow too */
|
||||||
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
|
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -705,6 +705,23 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
|||||||
r = 1;
|
r = 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case KVM_CAP_PPC_AIL_MODE_3:
|
||||||
|
r = 0;
|
||||||
|
/*
|
||||||
|
* KVM PR, POWER7, and some POWER9s don't support AIL=3 mode.
|
||||||
|
* The POWER9s can support it if the guest runs in hash mode,
|
||||||
|
* but QEMU doesn't necessarily query the capability in time.
|
||||||
|
*/
|
||||||
|
if (hv_enabled) {
|
||||||
|
if (kvmhv_on_pseries()) {
|
||||||
|
if (pseries_reloc_on_exception())
|
||||||
|
r = 1;
|
||||||
|
} else if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
|
||||||
|
!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
|
||||||
|
r = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
r = 0;
|
r = 0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -353,6 +353,14 @@ static void pseries_lpar_idle(void)
|
|||||||
pseries_idle_epilog();
|
pseries_idle_epilog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pseries_reloc_on_exception_enabled;
|
||||||
|
|
||||||
|
bool pseries_reloc_on_exception(void)
|
||||||
|
{
|
||||||
|
return pseries_reloc_on_exception_enabled;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pseries_reloc_on_exception);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable relocation on during exceptions. This has partition wide scope and
|
* Enable relocation on during exceptions. This has partition wide scope and
|
||||||
* may take a while to complete, if it takes longer than one second we will
|
* may take a while to complete, if it takes longer than one second we will
|
||||||
@@ -377,6 +385,7 @@ bool pseries_enable_reloc_on_exc(void)
|
|||||||
" on exceptions: %ld\n", rc);
|
" on exceptions: %ld\n", rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pseries_reloc_on_exception_enabled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +413,9 @@ void pseries_disable_reloc_on_exc(void)
|
|||||||
break;
|
break;
|
||||||
mdelay(get_longbusy_msecs(rc));
|
mdelay(get_longbusy_msecs(rc));
|
||||||
}
|
}
|
||||||
if (rc != H_SUCCESS)
|
if (rc == H_SUCCESS)
|
||||||
|
pseries_reloc_on_exception_enabled = false;
|
||||||
|
else
|
||||||
pr_warn("Warning: Failed to disable relocation on exceptions: %ld\n",
|
pr_warn("Warning: Failed to disable relocation on exceptions: %ld\n",
|
||||||
rc);
|
rc);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user