aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/hvcall.h9
-rw-r--r--arch/powerpc/kvm/book3s_pr.c18
-rw-r--r--arch/powerpc/platforms/pseries/setup.c8
3 files changed, 32 insertions, 3 deletions
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 0975e5c0bb19..4bc2c3dad6ad 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -395,6 +395,15 @@ static inline unsigned long cmo_get_page_size(void)
395{ 395{
396 return CMO_PageSize; 396 return CMO_PageSize;
397} 397}
398
399extern long pSeries_enable_reloc_on_exc(void);
400extern long pSeries_disable_reloc_on_exc(void);
401
402#else
403
404#define pSeries_enable_reloc_on_exc() do {} while (0)
405#define pSeries_disable_reloc_on_exc() do {} while (0)
406
398#endif /* CONFIG_PPC_PSERIES */ 407#endif /* CONFIG_PPC_PSERIES */
399 408
400#endif /* __ASSEMBLY__ */ 409#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 28d38adeca73..67e4708388a0 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -34,6 +34,7 @@
34#include <asm/kvm_book3s.h> 34#include <asm/kvm_book3s.h>
35#include <asm/mmu_context.h> 35#include <asm/mmu_context.h>
36#include <asm/switch_to.h> 36#include <asm/switch_to.h>
37#include <asm/firmware.h>
37#include <linux/gfp.h> 38#include <linux/gfp.h>
38#include <linux/sched.h> 39#include <linux/sched.h>
39#include <linux/vmalloc.h> 40#include <linux/vmalloc.h>
@@ -1284,12 +1285,21 @@ void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot)
1284{ 1285{
1285} 1286}
1286 1287
1288static unsigned int kvm_global_user_count = 0;
1289static DEFINE_SPINLOCK(kvm_global_user_count_lock);
1290
1287int kvmppc_core_init_vm(struct kvm *kvm) 1291int kvmppc_core_init_vm(struct kvm *kvm)
1288{ 1292{
1289#ifdef CONFIG_PPC64 1293#ifdef CONFIG_PPC64
1290 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); 1294 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables);
1291#endif 1295#endif
1292 1296
1297 if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
1298 spin_lock(&kvm_global_user_count_lock);
1299 if (++kvm_global_user_count == 1)
1300 pSeries_disable_reloc_on_exc();
1301 spin_unlock(&kvm_global_user_count_lock);
1302 }
1293 return 0; 1303 return 0;
1294} 1304}
1295 1305
@@ -1298,6 +1308,14 @@ void kvmppc_core_destroy_vm(struct kvm *kvm)
1298#ifdef CONFIG_PPC64 1308#ifdef CONFIG_PPC64
1299 WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); 1309 WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables));
1300#endif 1310#endif
1311
1312 if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
1313 spin_lock(&kvm_global_user_count_lock);
1314 BUG_ON(kvm_global_user_count == 0);
1315 if (--kvm_global_user_count == 0)
1316 pSeries_enable_reloc_on_exc();
1317 spin_unlock(&kvm_global_user_count_lock);
1318 }
1301} 1319}
1302 1320
1303static int kvmppc_book3s_init(void) 1321static int kvmppc_book3s_init(void)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ca55882465d6..1890730354bb 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -375,7 +375,7 @@ static void pSeries_idle(void)
375 * to ever be a problem in practice we can move this into a kernel thread to 375 * to ever be a problem in practice we can move this into a kernel thread to
376 * finish off the process later in boot. 376 * finish off the process later in boot.
377 */ 377 */
378static int __init pSeries_enable_reloc_on_exc(void) 378long pSeries_enable_reloc_on_exc(void)
379{ 379{
380 long rc; 380 long rc;
381 unsigned int delay, total_delay = 0; 381 unsigned int delay, total_delay = 0;
@@ -397,9 +397,9 @@ static int __init pSeries_enable_reloc_on_exc(void)
397 mdelay(delay); 397 mdelay(delay);
398 } 398 }
399} 399}
400EXPORT_SYMBOL(pSeries_enable_reloc_on_exc);
400 401
401#ifdef CONFIG_KEXEC 402long pSeries_disable_reloc_on_exc(void)
402static long pSeries_disable_reloc_on_exc(void)
403{ 403{
404 long rc; 404 long rc;
405 405
@@ -410,7 +410,9 @@ static long pSeries_disable_reloc_on_exc(void)
410 mdelay(get_longbusy_msecs(rc)); 410 mdelay(get_longbusy_msecs(rc));
411 } 411 }
412} 412}
413EXPORT_SYMBOL(pSeries_disable_reloc_on_exc);
413 414
415#ifdef CONFIG_KEXEC
414static void pSeries_machine_kexec(struct kimage *image) 416static void pSeries_machine_kexec(struct kimage *image)
415{ 417{
416 long rc; 418 long rc;