page-states.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. * Copyright IBM Corp. 2008
  3. *
  4. * Guest page hinting for unused pages.
  5. *
  6. * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/errno.h>
  10. #include <linux/types.h>
  11. #include <linux/mm.h>
  12. #include <linux/init.h>
  13. #define ESSA_SET_STABLE 1
  14. #define ESSA_SET_UNUSED 2
  15. static int cmma_flag = 1;
  16. static int __init cmma(char *str)
  17. {
  18. char *parm;
  19. parm = strstrip(str);
  20. if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) {
  21. cmma_flag = 1;
  22. return 1;
  23. }
  24. cmma_flag = 0;
  25. if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0)
  26. return 1;
  27. return 0;
  28. }
  29. __setup("cmma=", cmma);
  30. void __init cmma_init(void)
  31. {
  32. register unsigned long tmp asm("0") = 0;
  33. register int rc asm("1") = -EOPNOTSUPP;
  34. if (!cmma_flag)
  35. return;
  36. asm volatile(
  37. " .insn rrf,0xb9ab0000,%1,%1,0,0\n"
  38. "0: la %0,0\n"
  39. "1:\n"
  40. EX_TABLE(0b,1b)
  41. : "+&d" (rc), "+&d" (tmp));
  42. if (rc)
  43. cmma_flag = 0;
  44. }
  45. void arch_free_page(struct page *page, int order)
  46. {
  47. int i, rc;
  48. if (!cmma_flag)
  49. return;
  50. for (i = 0; i < (1 << order); i++)
  51. asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
  52. : "=&d" (rc)
  53. : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT),
  54. "i" (ESSA_SET_UNUSED));
  55. }
  56. void arch_alloc_page(struct page *page, int order)
  57. {
  58. int i, rc;
  59. if (!cmma_flag)
  60. return;
  61. for (i = 0; i < (1 << order); i++)
  62. asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
  63. : "=&d" (rc)
  64. : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT),
  65. "i" (ESSA_SET_STABLE));
  66. }