aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-gru')
-rw-r--r--drivers/misc/sgi-gru/grufile.c3
-rw-r--r--drivers/misc/sgi-gru/grukservices.c150
-rw-r--r--drivers/misc/sgi-gru/grulib.h3
-rw-r--r--drivers/misc/sgi-gru/grutables.h2
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
849int quicktest(void) 849static 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; 888done:
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
895static 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
929done:
930 kfree(p);
931 return ret;
932}
933
934static 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);
980done:
981 kfree(buf);
982 return ret;
983}
984
985/*
986 * Debugging only. User hook for various kernel tests
987 * of driver & gru.
988 */
989int 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
885int gru_kservices_init(struct gru_state *gru) 1008int 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);
662extern struct gru_mm_struct *gru_register_mmu_notifier(void); 661extern struct gru_mm_struct *gru_register_mmu_notifier(void);
663extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms); 662extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms);
664 663
664extern int gru_ktest(unsigned long arg);
665extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start, 665extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
666 unsigned long len); 666 unsigned long len);
667 667