gzvm_main.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2023 MediaTek Inc.
  4. */
  5. #include <linux/device.h>
  6. #include <linux/file.h>
  7. #include <linux/kdev_t.h>
  8. #include <linux/miscdevice.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/gzvm_drv.h>
  13. /**
  14. * gzvm_err_to_errno() - Convert geniezone return value to standard errno
  15. *
  16. * @err: Return value from geniezone function return
  17. *
  18. * Return: Standard errno
  19. */
  20. int gzvm_err_to_errno(unsigned long err)
  21. {
  22. int gz_err = (int)err;
  23. switch (gz_err) {
  24. case 0:
  25. return 0;
  26. case ERR_NO_MEMORY:
  27. return -ENOMEM;
  28. case ERR_INVALID_ARGS:
  29. return -EINVAL;
  30. case ERR_NOT_SUPPORTED:
  31. return -EOPNOTSUPP;
  32. case ERR_NOT_IMPLEMENTED:
  33. return -EOPNOTSUPP;
  34. case ERR_FAULT:
  35. return -EFAULT;
  36. default:
  37. break;
  38. }
  39. return -EINVAL;
  40. }
  41. /**
  42. * gzvm_dev_ioctl_check_extension() - Check if given capability is support
  43. * or not
  44. *
  45. * @gzvm: Pointer to struct gzvm
  46. * @args: Pointer in u64 from userspace
  47. *
  48. * Return:
  49. * * 0 - Supported, no error
  50. * * -EOPNOTSUPP - Unsupported
  51. * * -EFAULT - Failed to get data from userspace
  52. */
  53. long gzvm_dev_ioctl_check_extension(struct gzvm *gzvm, unsigned long args)
  54. {
  55. __u64 cap;
  56. void __user *argp = (void __user *)args;
  57. if (copy_from_user(&cap, argp, sizeof(uint64_t)))
  58. return -EFAULT;
  59. return gzvm_arch_check_extension(gzvm, cap, argp);
  60. }
  61. static long gzvm_dev_ioctl(struct file *filp, unsigned int cmd,
  62. unsigned long user_args)
  63. {
  64. long ret;
  65. switch (cmd) {
  66. case GZVM_CREATE_VM:
  67. ret = gzvm_dev_ioctl_create_vm(user_args);
  68. return ret;
  69. case GZVM_CHECK_EXTENSION:
  70. if (!user_args)
  71. return -EINVAL;
  72. ret = gzvm_dev_ioctl_check_extension(NULL, user_args);
  73. return ret;
  74. default:
  75. break;
  76. }
  77. return -ENOTTY;
  78. }
  79. static const struct file_operations gzvm_chardev_ops = {
  80. .unlocked_ioctl = gzvm_dev_ioctl,
  81. .llseek = noop_llseek,
  82. };
  83. static struct miscdevice gzvm_dev = {
  84. .minor = MISC_DYNAMIC_MINOR,
  85. .name = KBUILD_MODNAME,
  86. .fops = &gzvm_chardev_ops,
  87. };
  88. static int gzvm_drv_probe(struct platform_device *pdev)
  89. {
  90. int ret;
  91. if (gzvm_arch_probe() != 0) {
  92. dev_err(&pdev->dev, "Not found available conduit\n");
  93. return -ENODEV;
  94. }
  95. ret = misc_register(&gzvm_dev);
  96. if (ret)
  97. return ret;
  98. return gzvm_drv_irqfd_init();
  99. }
  100. static int gzvm_drv_remove(struct platform_device *pdev)
  101. {
  102. gzvm_drv_irqfd_exit();
  103. gzvm_destroy_all_vms();
  104. misc_deregister(&gzvm_dev);
  105. return 0;
  106. }
  107. static const struct of_device_id gzvm_of_match[] = {
  108. { .compatible = "mediatek,geniezone-hyp" },
  109. {/* sentinel */},
  110. };
  111. static struct platform_driver gzvm_driver = {
  112. .probe = gzvm_drv_probe,
  113. .remove = gzvm_drv_remove,
  114. .driver = {
  115. .name = KBUILD_MODNAME,
  116. .owner = THIS_MODULE,
  117. .of_match_table = gzvm_of_match,
  118. },
  119. };
  120. module_platform_driver(gzvm_driver);
  121. MODULE_DEVICE_TABLE(of, gzvm_of_match);
  122. MODULE_AUTHOR("MediaTek");
  123. MODULE_DESCRIPTION("GenieZone interface for VMM");
  124. MODULE_LICENSE("GPL");