diff --git a/client/hostinfo_unix.cpp b/client/hostinfo_unix.cpp
index e89a7f1..4da8a6c 100644
--- a/client/hostinfo_unix.cpp
+++ b/client/hostinfo_unix.cpp
@@ -440,6 +440,7 @@ static void parse_cpuinfo_linux(HOST_INFO& host) {
     bool vendor_found=false, model_found=false;
     bool cache_found=false, features_found=false;
     bool model_hack=false, vendor_hack=false;
+    long m;
     int n;
     int family=-1, model=-1, stepping=-1;
     char buf2[256];
@@ -466,6 +467,9 @@ static void parse_cpuinfo_linux(HOST_INFO& host) {
 #elif __ia64__
     strcpy(host.p_model, "IA-64 ");
     model_hack = true;
+#elif __arm__
+    strcpy(host.p_vendor, "ARM");
+    vendor_hack = vendor_found = true;
 #endif
 
     host.m_cache=-1;
@@ -504,6 +508,8 @@ static void parse_cpuinfo_linux(HOST_INFO& host) {
             strstr(buf, "family     : ") || strstr(buf, "model name : ")
 #elif __powerpc__ || __sparc__
             strstr(buf, "cpu\t\t: ")
+#elif __arm__
+            strstr(buf, "Processor\t: ")
 #else
             strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")
 #endif
@@ -578,6 +584,35 @@ static void parse_cpuinfo_linux(HOST_INFO& host) {
             sscanf(buf, "cache size\t: %d", &n);
             host.m_cache = n*1024;
         }
+#ifdef HAVE_UNISTD_H
+        if (!cache_found) {
+            // Last-ditch effort to grok the cache size.
+#ifdef _SC_LEVEL1_DCACHE_SIZE        
+            m = sysconf(_SC_LEVEL1_DCACHE_SIZE);
+            if (m > host.m_cache)
+                host.m_cache = m;
+#endif
+#ifdef _SC_LEVEL2_CACHE_SIZE
+            m = sysconf(_SC_LEVEL2_CACHE_SIZE);
+            if (m > host.m_cache)
+                host.m_cache = m;
+#endif
+#ifdef _SC_LEVEL3_CACHE_SIZE
+            m = sysconf(_SC_LEVEL3_CACHE_SIZE);
+            if (m > host.m_cache)
+                host.m_cache = m;
+#endif
+#ifdef _SC_LEVEL4_CACHE_SIZE
+            m = sysconf(_SC_LEVEL4_CACHE_SIZE);
+            if (m > host.m_cache)
+                host.m_cache = m;
+#endif                
+            if (host.m_cache > 0)
+                cache_found = true;
+            else
+                host.m_cache = -1;
+        }
+#endif // HAVE_UNISTD_H
 #endif
         if (!features_found) {
             // Some versions of the linux kernel call them flags,
@@ -589,6 +624,8 @@ static void parse_cpuinfo_linux(HOST_INFO& host) {
                 strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
             } else if ((strstr(buf, "features   : ") == buf)) {    /* ia64 */
                 strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
+            } else if ((strstr(buf, "Features\t: ") == buf)) { /* arm */
+               strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
             }
             if (strlen(features)) {
                 features_found = true;
diff --git a/client/hostinfo_unix_test.cpp b/client/hostinfo_unix_test.cpp
index 76ae872..6ca5988 100644
--- a/client/hostinfo_unix_test.cpp
+++ b/client/hostinfo_unix_test.cpp
@@ -15,8 +15,10 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
 
-#include <cstdio>
-#include <cstring>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #define false 0
 #define true 1
@@ -29,6 +31,7 @@ int main(void) {
     bool cache_found=false, features_found=false;
     bool icache_found=false,dcache_found=false;
     bool model_hack=false, vendor_hack=false;
+    long m;
     int n;
     int family=-1, model=-1, stepping=-1;
     char  p_vendor[256], p_model[256];
@@ -37,7 +40,7 @@ int main(void) {
 
 
     FILE* f = fopen("/proc/cpuinfo", "r");
-    if (!f) return;
+    if (!f) return (EXIT_FAILURE);
 
 #ifdef __mips__
     strcpy(p_model, "MIPS ");
@@ -51,6 +54,9 @@ int main(void) {
 #elif __ia64__
     strcpy(p_model, "IA-64 ");
     model_hack = true;
+#elif __arm__
+    strcpy(p_vendor, "ARM ");
+    vendor_hack = vendor_found = true;
 #endif
 
     strcpy(features, "");
@@ -68,29 +74,33 @@ int main(void) {
         strstr(buf, "type\t\t: ")
 #elif __alpha__
         strstr(buf, "cpu\t\t\t: ")
+#elif __arm__
+        strstr(buf, "CPU architecture: ")
 #else
-    strstr(buf, "vendor_id\t: ") || strstr(buf, "system type\t\t: ")
+        strstr(buf, "vendor_id\t: ") || strstr(buf, "system type\t\t: ")
 #endif
         ) {
             if (!vendor_hack && !vendor_found) {
                 vendor_found = true;
                 strlcpy(p_vendor, strchr(buf, ':') + 2, sizeof(p_vendor));
             } else if (!vendor_found) {
-            vendor_found = true;
-        strlcpy(buf2, strchr(buf, ':') + 2, sizeof(p_vendor) - strlen(p_vendor) - 1);
-        strcat(p_vendor, buf2);
-        }
+                vendor_found = true;
+                strlcpy(buf2, strchr(buf, ':') + 2, sizeof(p_vendor) - strlen(p_vendor) - 1);
+                strcat(p_vendor, buf2);
+            }
         }
 
         if (
 #ifdef __ia64__
-        strstr(buf, "family     : ") || strstr(buf, "model name : ")
+            strstr(buf, "family     : ") || strstr(buf, "model name : ")
 #elif __powerpc__ || __sparc__
-        strstr(buf, "cpu\t\t: ")
+            strstr(buf, "cpu\t\t: ")
+#elif __arm__
+            strstr(buf, "Processor\t: ")
 #else
-    strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")
+            strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")
 #endif
-                ) {
+        ) {
             if (!model_hack && !model_found) {
                 model_found = true;
 #ifdef __powerpc__
@@ -160,6 +170,32 @@ int main(void) {
             sscanf(buf, "cache size\t: %d", &n);
             m_cache = n*1024;
         }
+        if (!cache_found) {
+#ifdef _SC_LEVEL1_DCACHE_SIZE        
+            m = sysconf(_SC_LEVEL1_DCACHE_SIZE);
+            if (m > m_cache)
+                m_cache = m;
+#endif
+#ifdef _SC_LEVEL2_CACHE_SIZE
+            m = sysconf(_SC_LEVEL2_CACHE_SIZE);
+            if (m > m_cache)
+                m_cache = m;
+#endif
+#ifdef _SC_LEVEL3_CACHE_SIZE
+            m = sysconf(_SC_LEVEL3_CACHE_SIZE);
+            if (m > m_cache)
+                m_cache = m;
+#endif
+#ifdef _SC_LEVEL4_CACHE_SIZE
+            m = sysconf(_SC_LEVEL4_CACHE_SIZE);
+            if (m > m_cache)
+                m_cache = m;
+#endif                
+            if (m_cache > 0)
+                cache_found = true;
+            else
+                m_cache = -1;
+        }
 #endif
         if (!features_found) {
             // Some versions of the linux kernel call them flags,
@@ -170,6 +206,8 @@ int main(void) {
                 strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
             } else if ((strstr(buf, "features   : ") == buf)) { /* ia64 */
                 strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
+            } else if ((strstr(buf, "Features\t: ") == buf)) { /* arm */
+                strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
             }
             if (strlen(features)) {
                 features_found = true;
@@ -204,5 +242,5 @@ int main(void) {
         p_vendor, m_cache, model_buf
     );
     fclose(f);
-    return 0;
+    return (EXIT_SUCCESS);
 }
