diff options
Diffstat (limited to 'arch/ppc64')
-rw-r--r-- | arch/ppc64/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/prom.c | 19 | ||||
-rw-r--r-- | arch/ppc64/kernel/traps.c | 2 |
3 files changed, 20 insertions, 3 deletions
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index fe05f3fbf9d0..92a744c31ab1 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -922,7 +922,9 @@ fp_unavailable_common: | |||
922 | altivec_unavailable_common: | 922 | altivec_unavailable_common: |
923 | EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN) | 923 | EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN) |
924 | #ifdef CONFIG_ALTIVEC | 924 | #ifdef CONFIG_ALTIVEC |
925 | BEGIN_FTR_SECTION | ||
925 | bne .load_up_altivec /* if from user, just load it up */ | 926 | bne .load_up_altivec /* if from user, just load it up */ |
927 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
926 | #endif | 928 | #endif |
927 | bl .save_nvgprs | 929 | bl .save_nvgprs |
928 | addi r3,r1,STACK_FRAME_OVERHEAD | 930 | addi r3,r1,STACK_FRAME_OVERHEAD |
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 01739d5c47c7..b08aac68baff 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -885,6 +885,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
885 | const char *full_path, void *data) | 885 | const char *full_path, void *data) |
886 | { | 886 | { |
887 | char *type = get_flat_dt_prop(node, "device_type", NULL); | 887 | char *type = get_flat_dt_prop(node, "device_type", NULL); |
888 | u32 *prop; | ||
888 | 889 | ||
889 | /* We are scanning "cpu" nodes only */ | 890 | /* We are scanning "cpu" nodes only */ |
890 | if (type == NULL || strcmp(type, "cpu") != 0) | 891 | if (type == NULL || strcmp(type, "cpu") != 0) |
@@ -916,6 +917,20 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
916 | } | 917 | } |
917 | } | 918 | } |
918 | 919 | ||
920 | /* Check if we have a VMX and eventually update CPU features */ | ||
921 | prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL); | ||
922 | if (prop && (*prop) > 0) { | ||
923 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | ||
924 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | ||
925 | } | ||
926 | |||
927 | /* Same goes for Apple's "altivec" property */ | ||
928 | prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL); | ||
929 | if (prop) { | ||
930 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | ||
931 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | ||
932 | } | ||
933 | |||
919 | return 0; | 934 | return 0; |
920 | } | 935 | } |
921 | 936 | ||
@@ -1104,7 +1119,9 @@ void __init early_init_devtree(void *params) | |||
1104 | 1119 | ||
1105 | DBG("Scanning CPUs ...\n"); | 1120 | DBG("Scanning CPUs ...\n"); |
1106 | 1121 | ||
1107 | /* Retreive hash table size from flattened tree */ | 1122 | /* Retreive hash table size from flattened tree plus other |
1123 | * CPU related informations (altivec support, boot CPU ID, ...) | ||
1124 | */ | ||
1108 | scan_flat_dt(early_init_dt_scan_cpus, NULL); | 1125 | scan_flat_dt(early_init_dt_scan_cpus, NULL); |
1109 | 1126 | ||
1110 | /* If hash size wasn't obtained above, we calculate it now based on | 1127 | /* If hash size wasn't obtained above, we calculate it now based on |
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c index 10fc61f3f6a4..7e52cb2605e0 100644 --- a/arch/ppc64/kernel/traps.c +++ b/arch/ppc64/kernel/traps.c | |||
@@ -450,14 +450,12 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs) | |||
450 | 450 | ||
451 | void altivec_unavailable_exception(struct pt_regs *regs) | 451 | void altivec_unavailable_exception(struct pt_regs *regs) |
452 | { | 452 | { |
453 | #ifndef CONFIG_ALTIVEC | ||
454 | if (user_mode(regs)) { | 453 | if (user_mode(regs)) { |
455 | /* A user program has executed an altivec instruction, | 454 | /* A user program has executed an altivec instruction, |
456 | but this kernel doesn't support altivec. */ | 455 | but this kernel doesn't support altivec. */ |
457 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 456 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
458 | return; | 457 | return; |
459 | } | 458 | } |
460 | #endif | ||
461 | printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " | 459 | printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " |
462 | "%lx at %lx\n", regs->trap, regs->nip); | 460 | "%lx at %lx\n", regs->trap, regs->nip); |
463 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); | 461 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); |