* cpuid.h: Add missing copyright header. Fix formatting. Use uint32_t
instead of unsigned throughout. Change functions to static inline and always inline. (cpuid): Add parameter to set ecx, allowing to request extended CPUID info. * fhandler_proc.cc (format_proc_cpuinfo): Use uint32_t instead of unsigned throughout. Add fake decimal places to MHz info. Handle more feature flags. * fhandler_random.cc (fhandler_dev_random::write): Allow up to 4K input to add entropy. * syscalls.cc: Drop including cpuid.h.
This commit is contained in:
		| @@ -1,3 +1,17 @@ | ||||
| 2014-08-11  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* cpuid.h: Add missing copyright header.  Fix formatting.  Use uint32_t | ||||
| 	instead of unsigned throughout.  Change functions to static inline and | ||||
| 	always inline. | ||||
| 	(cpuid): Add parameter to set ecx, allowing to request extended CPUID | ||||
| 	info. | ||||
| 	* fhandler_proc.cc (format_proc_cpuinfo): Use uint32_t instead of | ||||
| 	unsigned throughout.  Add fake decimal places to MHz info.  Handle more | ||||
| 	feature flags. | ||||
| 	* fhandler_random.cc (fhandler_dev_random::write): Allow up to 4K | ||||
| 	input to add entropy. | ||||
| 	* syscalls.cc: Drop including cpuid.h. | ||||
|  | ||||
| 2014-08-07  Yaakov Selkowitz  <yselkowi@redhat.com> | ||||
|  | ||||
| 	* common.din (__cxa_finalize): Export. | ||||
|   | ||||
| @@ -1,54 +1,64 @@ | ||||
| /* cpuid.h: Define cpuid instruction | ||||
|  | ||||
|    Copyright 2003, 2012, 2014 Red Hat, Inc. | ||||
|  | ||||
| This file is part of Cygwin. | ||||
|  | ||||
| This software is a copyrighted work licensed under the terms of the | ||||
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||
| details. */ | ||||
|  | ||||
| #ifndef CPUID_H | ||||
| #define CPUID_H | ||||
|  | ||||
| extern inline void | ||||
| cpuid (unsigned *a, unsigned *b, unsigned *c, unsigned *d, unsigned in) | ||||
| static inline void __attribute ((always_inline)) | ||||
| cpuid (uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t ain, | ||||
|        uint32_t cin = 0) | ||||
| { | ||||
|   asm ("cpuid" | ||||
|        : "=a" (*a), | ||||
| 	 "=b" (*b), | ||||
| 	 "=c" (*c), | ||||
| 	 "=d" (*d) | ||||
|        : "a" (in)); | ||||
|   asm volatile ("cpuid" | ||||
| 		: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) | ||||
| 		: "a" (ain), "c" (cin)); | ||||
| } | ||||
|  | ||||
| #ifdef __x86_64__ | ||||
| extern inline bool | ||||
| can_set_flag (register unsigned long flag) | ||||
| static inline bool __attribute ((always_inline)) | ||||
| can_set_flag (register uint32_t long flag) | ||||
| { | ||||
|   register unsigned long r1, r2; | ||||
|   asm("pushfq\n" | ||||
|       "popq %0\n" | ||||
|       "movq %0, %1\n" | ||||
|       "xorq %2, %0\n" | ||||
|       "pushq %0\n" | ||||
|       "popfq\n" | ||||
|       "pushfq\n" | ||||
|       "popq %0\n" | ||||
|       "pushq %1\n" | ||||
|       "popfq\n" | ||||
|       : "=&r" (r1), "=&r" (r2) | ||||
|       : "ir" (flag) | ||||
|   register uint32_t long r1, r2; | ||||
|  | ||||
|   asm volatile ("pushfq\n" | ||||
| 		"popq %0\n" | ||||
| 		"movq %0, %1\n" | ||||
| 		"xorq %2, %0\n" | ||||
| 		"pushq %0\n" | ||||
| 		"popfq\n" | ||||
| 		"pushfq\n" | ||||
| 		"popq %0\n" | ||||
| 		"pushq %1\n" | ||||
| 		"popfq\n" | ||||
| 		: "=&r" (r1), "=&r" (r2) | ||||
| 		: "ir" (flag) | ||||
|   ); | ||||
|   return ((r1 ^ r2) & flag) != 0; | ||||
| } | ||||
| #else | ||||
| extern inline bool | ||||
| can_set_flag (register unsigned flag) | ||||
| static inline bool __attribute ((always_inline)) | ||||
| can_set_flag (register uint32_t flag) | ||||
| { | ||||
|   register unsigned r1, r2; | ||||
|   asm("pushfl\n" | ||||
|       "popl %0\n" | ||||
|       "movl %0, %1\n" | ||||
|       "xorl %2, %0\n" | ||||
|       "pushl %0\n" | ||||
|       "popfl\n" | ||||
|       "pushfl\n" | ||||
|       "popl %0\n" | ||||
|       "pushl %1\n" | ||||
|       "popfl\n" | ||||
|       : "=&r" (r1), "=&r" (r2) | ||||
|       : "ir" (flag) | ||||
|   register uint32_t r1, r2; | ||||
|  | ||||
|   asm volatile ("pushfl\n" | ||||
| 		"popl %0\n" | ||||
| 		"movl %0, %1\n" | ||||
| 		"xorl %2, %0\n" | ||||
| 		"pushl %0\n" | ||||
| 		"popfl\n" | ||||
| 		"pushfl\n" | ||||
| 		"popl %0\n" | ||||
| 		"pushl %1\n" | ||||
| 		"popfl\n" | ||||
| 		: "=&r" (r1), "=&r" (r2) | ||||
| 		: "ir" (flag) | ||||
|   ); | ||||
|   return ((r1 ^ r2) & flag) != 0; | ||||
| } | ||||
|   | ||||
| @@ -601,7 +601,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
|     char s[BUFSIZE]; | ||||
|     WCHAR w[BUFSIZE / sizeof (WCHAR)]; | ||||
|     DWORD d; | ||||
|     unsigned m[13]; | ||||
|     uint32_t m[13]; | ||||
|   } in_buf; | ||||
|   tmp_pathbuf tp; | ||||
|  | ||||
| @@ -698,7 +698,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 	  RtlQueryRegistryValues (RTL_REGISTRY_ABSOLUTE, cpu_key, tab, | ||||
| 				  NULL, NULL); | ||||
| 	  bufptr += __small_sprintf (bufptr, "processor\t: %d\n", cpu_number); | ||||
| 	  unsigned maxf, vendor_id[4], unused; | ||||
| 	  uint32_t maxf, vendor_id[4], unused; | ||||
| 	  cpuid (&maxf, &vendor_id[0], &vendor_id[2], &vendor_id[1], 0); | ||||
| 	  maxf &= 0xffff; | ||||
| 	  vendor_id[3] = 0; | ||||
| @@ -714,23 +714,23 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 				     (char *)vendor_id); | ||||
| 	  if (maxf >= 1) | ||||
| 	    { | ||||
| 	      unsigned features2, features1, extra_info, cpuid_sig; | ||||
| 	      uint32_t features2, features1, extra_info, cpuid_sig; | ||||
| 	      cpuid (&cpuid_sig, &extra_info, &features2, &features1, 1); | ||||
| 	      /* unsigned extended_family = (cpuid_sig & 0x0ff00000) >> 20, | ||||
| 	      /* uint32_t extended_family = (cpuid_sig & 0x0ff00000) >> 20, | ||||
| 			  extended_model  = (cpuid_sig & 0x000f0000) >> 16, | ||||
| 			  type		  = (cpuid_sig & 0x00003000) >> 12; */ | ||||
| 	      unsigned family		= (cpuid_sig & 0x00000f00) >> 8, | ||||
| 	      uint32_t family		= (cpuid_sig & 0x00000f00) >> 8, | ||||
| 		       model		= (cpuid_sig & 0x000000f0) >> 4, | ||||
| 		       stepping		= cpuid_sig & 0x0000000f; | ||||
| 	      /* Not printed on Linux */ | ||||
| 	      //unsigned brand_id		= extra_info & 0x0000000f; | ||||
| 	      //unsigned cpu_count	= (extra_info & 0x00ff0000) >> 16; | ||||
| 	      unsigned apic_id		= (extra_info & 0xff000000) >> 24; | ||||
| 	      //uint32_t brand_id		= extra_info & 0x0000000f; | ||||
| 	      //uint32_t cpu_count	= (extra_info & 0x00ff0000) >> 16; | ||||
| 	      uint32_t apic_id		= (extra_info & 0xff000000) >> 24; | ||||
| 	      if (family == 15) | ||||
| 		family += (cpuid_sig >> 20) & 0xff; | ||||
| 	      if (family >= 6) | ||||
| 		model += ((cpuid_sig >> 16) & 0x0f) << 4; | ||||
| 	      unsigned maxe = 0; | ||||
| 	      uint32_t maxe = 0; | ||||
| 	      cpuid (&maxe, &unused, &unused, &unused, 0x80000000); | ||||
| 	      if (maxe >= 0x80000004) | ||||
| 		{ | ||||
| @@ -757,7 +757,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 		cache_alignment = clflush * 2; | ||||
| 	      if (maxe >= 0x80000005) /* L1 Cache and TLB Identifiers. */ | ||||
| 		{ | ||||
| 		  unsigned data_cache, inst_cache; | ||||
| 		  uint32_t data_cache, inst_cache; | ||||
| 		  cpuid (&unused, &unused, &data_cache, &inst_cache, | ||||
| 			 0x80000005); | ||||
|  | ||||
| @@ -766,7 +766,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 		} | ||||
| 	      if (maxe >= 0x80000006) /* L2 Cache and L2 TLB Identifiers. */ | ||||
| 		{ | ||||
| 		  unsigned tlb, l2; | ||||
| 		  uint32_t tlb, l2; | ||||
| 		  cpuid (&unused, &tlb, &l2, &unused, 0x80000006); | ||||
|  | ||||
| 		  cache_size = l2 >> 16; | ||||
| @@ -776,7 +776,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 						 "model\t\t: %d\n" | ||||
| 						 "model name\t: %s\n" | ||||
| 						 "stepping\t: %d\n" | ||||
| 						 "cpu MHz\t\t: %d\n", | ||||
| 						 "cpu MHz\t\t: %d.000\n", | ||||
| 					 family, | ||||
| 					 model, | ||||
| 					 in_buf.s + strspn (in_buf.s, " 	"), | ||||
| @@ -789,7 +789,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 	      /* Recognize multi-core CPUs. */ | ||||
| 	      if (is_amd && maxe >= 0x80000008) | ||||
| 		{ | ||||
| 		  unsigned core_info; | ||||
| 		  uint32_t core_info; | ||||
| 		  cpuid (&unused, &unused, &core_info, &unused, 0x80000008); | ||||
|  | ||||
| 		  int max_cores = 1 + (core_info & 0xff); | ||||
| @@ -888,28 +888,27 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
|  | ||||
| 	      if (is_amd && maxe >= 0x80000001) | ||||
| 		{ | ||||
| 		  unsigned features; | ||||
| 		  cpuid (&unused, &unused, &unused, &features, 0x80000001); | ||||
| 		  cpuid (&unused, &unused, &unused, &features1, 0x80000001); | ||||
|  | ||||
| 		  if (features & (1 << 11)) | ||||
| 		  if (features1 & (1 << 11)) | ||||
| 		    print (" syscall"); | ||||
| 		  if (features & (1 << 19)) /* Huh?  Not in AMD64 specs. */ | ||||
| 		  if (features1 & (1 << 19)) /* Huh?  Not in AMD64 specs. */ | ||||
| 		    print (" mp"); | ||||
| 		  if (features & (1 << 20)) | ||||
| 		  if (features1 & (1 << 20)) | ||||
| 		    print (" nx"); | ||||
| 		  if (features & (1 << 22)) | ||||
| 		  if (features1 & (1 << 22)) | ||||
| 		    print (" mmxext"); | ||||
| 		  if (features & (1 << 25)) | ||||
| 		  if (features1 & (1 << 25)) | ||||
| 		    print (" fxsr_opt"); | ||||
| 		  if (features & (1 << 26)) | ||||
| 		  if (features1 & (1 << 26)) | ||||
| 		    print (" pdpe1gb"); | ||||
| 		  if (features & (1 << 27)) | ||||
| 		  if (features1 & (1 << 27)) | ||||
| 		    print (" rdtscp"); | ||||
| 		  if (features & (1 << 29)) | ||||
| 		  if (features1 & (1 << 29)) | ||||
| 		    print (" lm"); | ||||
| 		  if (features & (1 << 30)) /* 31th bit is on. */ | ||||
| 		  if (features1 & (1 << 30)) /* 31th bit is on. */ | ||||
| 		    print (" 3dnowext"); | ||||
| 		  if (features & (1 << 31)) /* 32th bit (highest) is on. */ | ||||
| 		  if (features1 & (1 << 31)) /* 32th bit (highest) is on. */ | ||||
| 		    print (" 3dnow"); | ||||
| 		} | ||||
|  | ||||
| @@ -966,48 +965,136 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
| 		    print (" osxsave"); | ||||
| 		  if (features2 & (1 << 28)) | ||||
| 		    print (" avx"); | ||||
| 		  if (features2 & (1 << 29)) | ||||
| 		    print (" f16c"); | ||||
| 		  if (features2 & (1 << 30)) | ||||
| 		    print (" rdrand"); | ||||
| 		  if (features2 & (1 << 31)) | ||||
| 		    print (" hypervisor"); | ||||
| 		} | ||||
|  | ||||
| 	      if (maxe >= 0x80000001) | ||||
| 		{ | ||||
| 		  unsigned features; | ||||
| 		  cpuid (&unused, &unused, &features, &unused, 0x80000001); | ||||
| 		  cpuid (&unused, &unused, &features1, &unused, 0x80000001); | ||||
|  | ||||
| 		  if (features & (1 << 0)) | ||||
| 		  if (features1 & (1 << 0)) | ||||
| 		    print (" lahf_lm"); | ||||
| 		  if (features & (1 << 1)) | ||||
| 		  if (features1 & (1 << 1)) | ||||
| 		    print (" cmp_legacy"); | ||||
| 		  if (is_amd) | ||||
| 		    { | ||||
| 		      if (features & (1 << 2)) | ||||
| 		      if (features1 & (1 << 2)) | ||||
| 			print (" svm"); | ||||
| 		      if (features & (1 << 3)) | ||||
| 		      if (features1 & (1 << 3)) | ||||
| 			print (" extapic"); | ||||
| 		      if (features & (1 << 4)) | ||||
| 		      if (features1 & (1 << 4)) | ||||
| 			print (" cr8_legacy"); | ||||
| 		      if (features & (1 << 5)) | ||||
| 		      if (features1 & (1 << 5)) | ||||
| 			print (" abm"); | ||||
| 		      if (features & (1 << 6)) | ||||
| 		      if (features1 & (1 << 6)) | ||||
| 			print (" sse4a"); | ||||
| 		      if (features & (1 << 7)) | ||||
| 		      if (features1 & (1 << 7)) | ||||
| 			print (" misalignsse"); | ||||
| 		      if (features & (1 << 8)) | ||||
| 		      if (features1 & (1 << 8)) | ||||
| 			print (" 3dnowprefetch"); | ||||
| 		      if (features & (1 << 9)) | ||||
| 		      if (features1 & (1 << 9)) | ||||
| 			print (" osvw"); | ||||
| 		    } | ||||
| 		  if (features & (1 << 10)) | ||||
| 		  if (features1 & (1 << 10)) | ||||
| 		    print (" ibs"); | ||||
| 		  if (is_amd) | ||||
| 		    { | ||||
| 		      if (features & (1 << 11)) | ||||
| 		      if (features1 & (1 << 11)) | ||||
| 			print (" sse5"); | ||||
| 		      if (features & (1 << 12)) | ||||
| 		      if (features1 & (1 << 12)) | ||||
| 			print (" skinit"); | ||||
| 		      if (features & (1 << 13)) | ||||
| 		      if (features1 & (1 << 13)) | ||||
| 			print (" wdt"); | ||||
| 		      if (features1 & (1 << 15)) | ||||
| 			print (" lwp"); | ||||
| 		      if (features1 & (1 << 16)) | ||||
| 			print (" fma4"); | ||||
| 		      if (features1 & (1 << 17)) | ||||
| 			print (" tce"); | ||||
| 		      if (features1 & (1 << 19)) | ||||
| 			print (" nodeid_msr"); | ||||
| 		      if (features1 & (1 << 21)) | ||||
| 			print (" tbm"); | ||||
| 		      if (features1 & (1 << 22)) | ||||
| 			print (" topoext"); | ||||
| 		      if (features1 & (1 << 23)) | ||||
| 			print (" perfctr_core"); | ||||
| 		      if (features1 & (1 << 24)) | ||||
| 			print (" perfctr_nb"); | ||||
| 		      if (features1 & (1 << 28)) | ||||
| 			print (" perfctr_l2"); | ||||
| 		    } | ||||
| 		} | ||||
| 	      if (is_intel) /* features scattered in various CPUID levels. */ | ||||
| 		{ | ||||
| 		  cpuid (&features1, &unused, &features2, &unused, 0x06); | ||||
|  | ||||
| 		  if (features1 & (1 << 1)) | ||||
| 		    print (" ida"); | ||||
| 		  if (features1 & (1 << 2)) | ||||
| 		    print (" arat"); | ||||
| 		  if (features2 & (1 << 3)) | ||||
| 		    print (" epb"); | ||||
|  | ||||
| 		  cpuid (&features2, &unused, &unused, &unused, 0x0d, 1); | ||||
| 		  if (features2 & (1 << 0)) | ||||
| 		    print (" xsaveopt"); | ||||
|  | ||||
| 		  if (features1 & (1 << 4)) | ||||
| 		    print (" pln"); | ||||
| 		  if (features1 & (1 << 6)) | ||||
| 		    print (" pts"); | ||||
| 		  if (features1 & (1 << 0)) | ||||
| 		    print (" dtherm"); | ||||
| 		} | ||||
| 	      if (is_intel) /* Extended feature flags */ | ||||
| 		{ | ||||
| 		  cpuid (&unused, &features1, &unused, &unused, 0x07, 0); | ||||
|  | ||||
| 		  if (features1 & (1 << 0)) | ||||
| 		    print (" fsgsbase"); | ||||
| 		  if (features1 & (1 << 1)) | ||||
| 		    print (" tsc_adjust"); | ||||
| 		  if (features1 & (1 << 3)) | ||||
| 		    print (" bmi1"); | ||||
| 		  if (features1 & (1 << 4)) | ||||
| 		    print (" hle"); | ||||
| 		  if (features1 & (1 << 5)) | ||||
| 		    print (" avx2"); | ||||
| 		  if (features1 & (1 << 7)) | ||||
| 		    print (" smep"); | ||||
| 		  if (features1 & (1 << 8)) | ||||
| 		    print (" bmi2"); | ||||
| 		  if (features1 & (1 << 9)) | ||||
| 		    print (" erms"); | ||||
| 		  if (features1 & (1 << 10)) | ||||
| 		    print (" invpcid"); | ||||
| 		  if (features1 & (1 << 11)) | ||||
| 		    print (" rtm"); | ||||
| 		  if (features1 & (1 << 14)) | ||||
| 		    print (" mpx"); | ||||
| 		  if (features1 & (1 << 16)) | ||||
| 		    print (" avx512f"); | ||||
| 		  if (features1 & (1 << 18)) | ||||
| 		    print (" rdseed"); | ||||
| 		  if (features1 & (1 << 19)) | ||||
| 		    print (" adx"); | ||||
| 		  if (features1 & (1 << 20)) | ||||
| 		    print (" smap"); | ||||
| 		  if (features1 & (1 << 23)) | ||||
| 		    print (" clflushopt"); | ||||
| 		  if (features1 & (1 << 26)) | ||||
| 		    print (" avx512pf"); | ||||
| 		  if (features1 & (1 << 27)) | ||||
| 		    print (" avx512er"); | ||||
| 		  if (features1 & (1 << 28)) | ||||
| 		    print (" avx512cd"); | ||||
| 		} | ||||
|  | ||||
| 	      print ("\n"); | ||||
|  | ||||
| @@ -1024,7 +1111,7 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
|  | ||||
| 	      if (maxe >= 0x80000008) /* Address size. */ | ||||
| 		{ | ||||
| 		  unsigned addr_size, phys, virt; | ||||
| 		  uint32_t addr_size, phys, virt; | ||||
| 		  cpuid (&addr_size, &unused, &unused, &unused, 0x80000008); | ||||
|  | ||||
| 		  phys = addr_size & 0xff; | ||||
| @@ -1040,24 +1127,24 @@ format_proc_cpuinfo (void *, char *&destbuf) | ||||
|  | ||||
| 	      if (maxe >= 0x80000007) /* Advanced power management. */ | ||||
| 		{ | ||||
| 		  cpuid (&unused, &unused, &unused, &features2, 0x80000007); | ||||
| 		  cpuid (&unused, &unused, &unused, &features1, 0x80000007); | ||||
|  | ||||
| 		  print ("power management:"); | ||||
| 		  if (features2 & (1 << 0)) | ||||
| 		  if (features1 & (1 << 0)) | ||||
| 		    print (" ts"); | ||||
| 		  if (features2 & (1 << 1)) | ||||
| 		  if (features1 & (1 << 1)) | ||||
| 		    print (" fid"); | ||||
| 		  if (features2 & (1 << 2)) | ||||
| 		  if (features1 & (1 << 2)) | ||||
| 		    print (" vid"); | ||||
| 		  if (features2 & (1 << 3)) | ||||
| 		  if (features1 & (1 << 3)) | ||||
| 		    print (" ttp"); | ||||
| 		  if (features2 & (1 << 4)) | ||||
| 		  if (features1 & (1 << 4)) | ||||
| 		    print (" tm"); | ||||
| 		  if (features2 & (1 << 5)) | ||||
| 		  if (features1 & (1 << 5)) | ||||
| 		    print (" stc"); | ||||
| 		  if (features2 & (1 << 6)) | ||||
| 		  if (features1 & (1 << 6)) | ||||
| 		    print (" 100mhzsteps"); | ||||
| 		  if (features2 & (1 << 7)) | ||||
| 		  if (features1 & (1 << 7)) | ||||
| 		    print (" hwpstate"); | ||||
| 		} | ||||
| 	    } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ details. */ | ||||
|  | ||||
| #include "winsup.h" | ||||
| #include <unistd.h> | ||||
| #include <sys/param.h> | ||||
| #include "cygerrno.h" | ||||
| #include "path.h" | ||||
| #include "fhandler.h" | ||||
| @@ -65,10 +66,10 @@ fhandler_dev_random::write (const void *ptr, size_t len) | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   /* Limit len to a value <= 512 since we don't want to overact. | ||||
|   /* Limit len to a value <= 4096 since we don't want to overact. | ||||
|      Copy to local buffer because CryptGenRandom violates const. */ | ||||
|   unsigned char buf[512]; | ||||
|   size_t limited_len = len <= 512 ? len : 512; | ||||
|   size_t limited_len = MIN (len, 4096); | ||||
|   unsigned char buf[limited_len]; | ||||
|   memcpy (buf, ptr, limited_len); | ||||
|  | ||||
|   /* Mess up system entropy source. Return error if device is /dev/random. */ | ||||
|   | ||||
| @@ -58,7 +58,6 @@ details. */ | ||||
| #include "pinfo.h" | ||||
| #include "shared_info.h" | ||||
| #include "cygheap.h" | ||||
| #include "cpuid.h" | ||||
| #include "registry.h" | ||||
| #include "environ.h" | ||||
| #include "tls_pbuf.h" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user