diff options
Diffstat (limited to 'drivers/misc/sgi-gru')
-rw-r--r-- | drivers/misc/sgi-gru/grufile.c | 3 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 150 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grulib.h | 3 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grutables.h | 2 |
4 files changed, 142 insertions, 16 deletions
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index b1567ce868e9..796ac704795e 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -250,6 +250,9 @@ static long gru_file_unlocked_ioctl(struct file *file, unsigned int req, | |||
250 | case GRU_USER_CALL_OS: | 250 | case GRU_USER_CALL_OS: |
251 | err = gru_handle_user_call_os(arg); | 251 | err = gru_handle_user_call_os(arg); |
252 | break; | 252 | break; |
253 | case GRU_KTEST: | ||
254 | err = gru_ktest(arg); | ||
255 | break; | ||
253 | case GRU_GET_CONFIG_INFO: | 256 | case GRU_GET_CONFIG_INFO: |
254 | err = gru_get_config_info(arg); | 257 | err = gru_get_config_info(arg); |
255 | break; | 258 | break; |
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index 9dff33cb72e3..7d7952b27e03 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
@@ -846,13 +846,14 @@ EXPORT_SYMBOL_GPL(gru_copy_gpa); | |||
846 | /* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/ | 846 | /* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/ |
847 | /* Temp - will delete after we gain confidence in the GRU */ | 847 | /* Temp - will delete after we gain confidence in the GRU */ |
848 | 848 | ||
849 | int quicktest(void) | 849 | static int quicktest0(unsigned long arg) |
850 | { | 850 | { |
851 | unsigned long word0; | 851 | unsigned long word0; |
852 | unsigned long word1; | 852 | unsigned long word1; |
853 | void *cb; | 853 | void *cb; |
854 | void *dsr; | 854 | void *dsr; |
855 | unsigned long *p; | 855 | unsigned long *p; |
856 | int ret = -EIO; | ||
856 | 857 | ||
857 | if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr)) | 858 | if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr)) |
858 | return MQE_BUG_NO_RESOURCES; | 859 | return MQE_BUG_NO_RESOURCES; |
@@ -861,26 +862,148 @@ int quicktest(void) | |||
861 | word1 = 0; | 862 | word1 = 0; |
862 | 863 | ||
863 | gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); | 864 | gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); |
864 | if (gru_wait(cb) != CBS_IDLE) | 865 | if (gru_wait(cb) != CBS_IDLE) { |
865 | BUG(); | 866 | printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n"); |
867 | goto done; | ||
868 | } | ||
866 | 869 | ||
867 | if (*p != MAGIC) | 870 | if (*p != MAGIC) { |
868 | BUG(); | 871 | printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p); |
872 | goto done; | ||
873 | } | ||
869 | gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); | 874 | gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); |
870 | if (gru_wait(cb) != CBS_IDLE) | 875 | if (gru_wait(cb) != CBS_IDLE) { |
871 | BUG(); | 876 | printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n"); |
872 | gru_free_cpu_resources(cb, dsr); | 877 | goto done; |
878 | } | ||
873 | 879 | ||
874 | if (word0 != word1 || word1 != MAGIC) { | 880 | if (word0 != word1 || word1 != MAGIC) { |
875 | printk | 881 | printk(KERN_DEBUG |
876 | ("GRU quicktest err: found 0x%lx, expected 0x%lx\n", | 882 | "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n", |
877 | word1, MAGIC); | 883 | word1, MAGIC); |
878 | BUG(); /* ZZZ should not be fatal */ | 884 | goto done; |
879 | } | 885 | } |
886 | ret = 0; | ||
880 | 887 | ||
881 | return 0; | 888 | done: |
889 | gru_free_cpu_resources(cb, dsr); | ||
890 | return ret; | ||
882 | } | 891 | } |
883 | 892 | ||
893 | #define ALIGNUP(p, q) ((void *)(((unsigned long)(p) + (q) - 1) & ~(q - 1))) | ||
894 | |||
895 | static int quicktest1(unsigned long arg) | ||
896 | { | ||
897 | struct gru_message_queue_desc mqd; | ||
898 | void *p, *mq; | ||
899 | unsigned long *dw; | ||
900 | int i, ret = -EIO; | ||
901 | char mes[GRU_CACHE_LINE_BYTES], *m; | ||
902 | |||
903 | /* Need 1K cacheline aligned that does not cross page boundary */ | ||
904 | p = kmalloc(4096, 0); | ||
905 | mq = ALIGNUP(p, 1024); | ||
906 | memset(mes, 0xee, sizeof(mes)); | ||
907 | dw = mq; | ||
908 | |||
909 | gru_create_message_queue(&mqd, mq, 8 * GRU_CACHE_LINE_BYTES, 0, 0, 0); | ||
910 | for (i = 0; i < 6; i++) { | ||
911 | mes[8] = i; | ||
912 | do { | ||
913 | ret = gru_send_message_gpa(&mqd, mes, sizeof(mes)); | ||
914 | } while (ret == MQE_CONGESTION); | ||
915 | if (ret) | ||
916 | break; | ||
917 | } | ||
918 | if (ret != MQE_QUEUE_FULL || i != 4) | ||
919 | goto done; | ||
920 | |||
921 | for (i = 0; i < 6; i++) { | ||
922 | m = gru_get_next_message(&mqd); | ||
923 | if (!m || m[8] != i) | ||
924 | break; | ||
925 | gru_free_message(&mqd, m); | ||
926 | } | ||
927 | ret = (i == 4) ? 0 : -EIO; | ||
928 | |||
929 | done: | ||
930 | kfree(p); | ||
931 | return ret; | ||
932 | } | ||
933 | |||
934 | static int quicktest2(unsigned long arg) | ||
935 | { | ||
936 | static DECLARE_COMPLETION(cmp); | ||
937 | unsigned long han; | ||
938 | int blade_id = 0; | ||
939 | int numcb = 4; | ||
940 | int ret = 0; | ||
941 | unsigned long *buf; | ||
942 | void *cb0, *cb; | ||
943 | int i, k, istatus, bytes; | ||
944 | |||
945 | bytes = numcb * 4 * 8; | ||
946 | buf = kmalloc(bytes, GFP_KERNEL); | ||
947 | if (!buf) | ||
948 | return -ENOMEM; | ||
949 | |||
950 | ret = -EBUSY; | ||
951 | han = gru_reserve_async_resources(blade_id, numcb, 0, &cmp); | ||
952 | if (!han) | ||
953 | goto done; | ||
954 | |||
955 | gru_lock_async_resource(han, &cb0, NULL); | ||
956 | memset(buf, 0xee, bytes); | ||
957 | for (i = 0; i < numcb; i++) | ||
958 | gru_vset(cb0 + i * GRU_HANDLE_STRIDE, uv_gpa(&buf[i * 4]), 0, | ||
959 | XTYPE_DW, 4, 1, IMA_INTERRUPT); | ||
960 | |||
961 | ret = 0; | ||
962 | for (k = 0; k < numcb; k++) { | ||
963 | gru_wait_async_cbr(han); | ||
964 | for (i = 0; i < numcb; i++) { | ||
965 | cb = cb0 + i * GRU_HANDLE_STRIDE; | ||
966 | istatus = gru_check_status(cb); | ||
967 | if (istatus == CBS_ACTIVE) | ||
968 | continue; | ||
969 | if (istatus == CBS_EXCEPTION) | ||
970 | ret = -EFAULT; | ||
971 | else if (buf[i] || buf[i + 1] || buf[i + 2] || | ||
972 | buf[i + 3]) | ||
973 | ret = -EIO; | ||
974 | } | ||
975 | } | ||
976 | BUG_ON(cmp.done); | ||
977 | |||
978 | gru_unlock_async_resource(han); | ||
979 | gru_release_async_resources(han); | ||
980 | done: | ||
981 | kfree(buf); | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | /* | ||
986 | * Debugging only. User hook for various kernel tests | ||
987 | * of driver & gru. | ||
988 | */ | ||
989 | int gru_ktest(unsigned long arg) | ||
990 | { | ||
991 | int ret = -EINVAL; | ||
992 | |||
993 | switch (arg & 0xff) { | ||
994 | case 0: | ||
995 | ret = quicktest0(arg); | ||
996 | break; | ||
997 | case 1: | ||
998 | ret = quicktest1(arg); | ||
999 | break; | ||
1000 | case 2: | ||
1001 | ret = quicktest2(arg); | ||
1002 | break; | ||
1003 | } | ||
1004 | return ret; | ||
1005 | |||
1006 | } | ||
884 | 1007 | ||
885 | int gru_kservices_init(struct gru_state *gru) | 1008 | int gru_kservices_init(struct gru_state *gru) |
886 | { | 1009 | { |
@@ -891,9 +1014,6 @@ int gru_kservices_init(struct gru_state *gru) | |||
891 | return 0; | 1014 | return 0; |
892 | 1015 | ||
893 | init_rwsem(&bs->bs_kgts_sema); | 1016 | init_rwsem(&bs->bs_kgts_sema); |
894 | |||
895 | if (gru_options & GRU_QUICKLOOK) | ||
896 | quicktest(); | ||
897 | return 0; | 1017 | return 0; |
898 | } | 1018 | } |
899 | 1019 | ||
diff --git a/drivers/misc/sgi-gru/grulib.h b/drivers/misc/sgi-gru/grulib.h index 6ab872665e7f..87586551d16f 100644 --- a/drivers/misc/sgi-gru/grulib.h +++ b/drivers/misc/sgi-gru/grulib.h | |||
@@ -56,6 +56,9 @@ | |||
56 | /* Get some config options (primarily for tests & emulator) */ | 56 | /* Get some config options (primarily for tests & emulator) */ |
57 | #define GRU_GET_CONFIG_INFO _IOWR(GRU_IOCTL_NUM, 51, void *) | 57 | #define GRU_GET_CONFIG_INFO _IOWR(GRU_IOCTL_NUM, 51, void *) |
58 | 58 | ||
59 | /* Various kernel self-tests */ | ||
60 | #define GRU_KTEST _IOWR(GRU_IOCTL_NUM, 52, void *) | ||
61 | |||
59 | #define CONTEXT_WINDOW_BYTES(th) (GRU_GSEG_PAGESIZE * (th)) | 62 | #define CONTEXT_WINDOW_BYTES(th) (GRU_GSEG_PAGESIZE * (th)) |
60 | #define THREAD_POINTER(p, th) (p + GRU_GSEG_PAGESIZE * (th)) | 63 | #define THREAD_POINTER(p, th) (p + GRU_GSEG_PAGESIZE * (th)) |
61 | 64 | ||
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h index ca81800146ff..6dfb3e69411f 100644 --- a/drivers/misc/sgi-gru/grutables.h +++ b/drivers/misc/sgi-gru/grutables.h | |||
@@ -258,7 +258,6 @@ extern struct mcs_op_statistic mcs_op_statistics[mcsop_last]; | |||
258 | 258 | ||
259 | #define OPT_DPRINT 1 | 259 | #define OPT_DPRINT 1 |
260 | #define OPT_STATS 2 | 260 | #define OPT_STATS 2 |
261 | #define GRU_QUICKLOOK 4 | ||
262 | 261 | ||
263 | 262 | ||
264 | #define IRQ_GRU 110 /* Starting IRQ number for interrupts */ | 263 | #define IRQ_GRU 110 /* Starting IRQ number for interrupts */ |
@@ -662,6 +661,7 @@ extern int gru_fault(struct vm_area_struct *, struct vm_fault *vmf); | |||
662 | extern struct gru_mm_struct *gru_register_mmu_notifier(void); | 661 | extern struct gru_mm_struct *gru_register_mmu_notifier(void); |
663 | extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms); | 662 | extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms); |
664 | 663 | ||
664 | extern int gru_ktest(unsigned long arg); | ||
665 | extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start, | 665 | extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start, |
666 | unsigned long len); | 666 | unsigned long len); |
667 | 667 | ||