dmesg_dumper_private.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #ifndef _DMESG_DUMPER_PRIVATE_H
  6. #define _DMESG_DUMPER_PRIVATE_H
  7. #include <linux/dev_printk.h>
  8. #include <linux/kmsg_dump.h>
  9. #include <soc/qcom/minidump.h>
  10. #define LOG_LINE_MAX 1024
  11. #define IV_LEN 12
  12. #define TAG_LEN 16
  13. #define KEY_LEN 16
  14. #define ALIGN_LEN 16
  15. #define AES_256_ENCRYPTED_KEY_SIZE 256
  16. /**
  17. * struct encrypt_data - the data struct of encrypted data
  18. * @frame_len: This encrypted frame size
  19. * @key: AES GCM encryption key wrapped up with OEM's public key
  20. * @iv: Nonce/IV used for current encryption
  21. * @tag: Tag used for validation
  22. * @cipher_log : The pointer to alive log with encrypt
  23. */
  24. struct encrypt_data {
  25. u64 frame_size;
  26. u8 key[AES_256_ENCRYPTED_KEY_SIZE];
  27. u8 iv[IV_LEN];
  28. u8 tag[TAG_LEN];
  29. u8 cipher_log[0];
  30. };
  31. /**
  32. * struct ddump_shm_hdr - the header of shared memory
  33. * @user_buf_len: The userspace buffer size when PVM request
  34. * @svm_dump_len: The actual log length SVM dump
  35. * @svm_is_suspend: Indicate SVM is in suspend mode or not
  36. * @data: The data need by decrypt when enable encrypt and
  37. * must be end of the hdr
  38. */
  39. struct ddump_shm_hdr {
  40. u64 user_buf_len;
  41. u64 svm_dump_len;
  42. bool svm_is_suspend;
  43. struct encrypt_data data;
  44. };
  45. /**
  46. * struct qcom_dmesg_dumper - the qcom dmesg dumper driver data
  47. * @device: The qcom dmesg dumper device
  48. * @dump: Kernel crash message dumper
  49. * @iter: Iterator for retrieving kernel messages
  50. * @res: The shared memory resource
  51. * @base: The virtual address of shared memory
  52. * @size: The size of shared memory
  53. * @label, peer_name, memparcel: The info need by gunyah and
  54. * secure buffer driver
  55. * @primary_vm: Is primary virtual machine or not
  56. * @rm_nb: The resource manager callback
  57. * @tx_dbl: The gunyah doorbell tx handler
  58. * @rx_dbl: The gunyah doorbell rx handler
  59. * @ddump_completion: The completion for synchronization when dump
  60. * alive log
  61. * @wakeup_source : Avoid system enter suspend when dump alive log
  62. * @md_entry : minidump entry
  63. */
  64. struct qcom_dmesg_dumper {
  65. struct device *dev;
  66. struct kmsg_dumper dump;
  67. struct kmsg_dump_iter iter;
  68. struct resource res;
  69. void *base;
  70. u64 size;
  71. u32 label, peer_name, memparcel;
  72. bool primary_vm;
  73. struct notifier_block rm_nb;
  74. void *tx_dbl;
  75. void *rx_dbl;
  76. struct completion ddump_completion;
  77. struct wakeup_source *wakeup_source;
  78. struct notifier_block gh_panic_nb;
  79. struct md_region md_entry;
  80. bool is_static;
  81. };
  82. #if IS_ENABLED(CONFIG_QCOM_VM_ALIVE_LOG_ENCRYPT)
  83. #define DDUMP_GET_USER_HDR (sizeof(struct encrypt_data) + TAG_LEN + ALIGN_LEN)
  84. #define DDUMP_GET_SHM_HDR (sizeof(struct ddump_shm_hdr) + TAG_LEN + ALIGN_LEN)
  85. int qcom_ddump_encrypt_init(struct device_node *node);
  86. void qcom_ddump_encrypt_exit(void);
  87. int qcom_ddump_alive_log_to_shm(struct qcom_dmesg_dumper *qdd,
  88. u64 user_size);
  89. #else /* !CONFIG_QCOM_VM_ALIVE_LOG_ENCRYPT */
  90. #define DDUMP_GET_USER_HDR 0
  91. #define DDUMP_GET_SHM_HDR offsetof(struct ddump_shm_hdr, data)
  92. static inline int qcom_ddump_encrypt_init(struct device_node *node)
  93. {
  94. return 0;
  95. }
  96. static inline void qcom_ddump_encrypt_exit(void)
  97. {}
  98. #endif /* CONFIG_QCOM_VM_ALIVE_LOG_ENCRYPT */
  99. #if IS_ENABLED(CONFIG_ARCH_QTI_VM)
  100. static inline u64 qcom_ddump_get_valid_size(struct qcom_dmesg_dumper *qdd,
  101. u64 user_size)
  102. {
  103. u64 user_valid_size, shm_valid_size;
  104. u64 user_hdr_size, shm_hdr_size;
  105. user_hdr_size = DDUMP_GET_USER_HDR;
  106. shm_hdr_size = DDUMP_GET_SHM_HDR;
  107. if (user_size < user_hdr_size) {
  108. dev_err(qdd->dev, "user buffer size should greater than %d\n", user_hdr_size);
  109. return 0;
  110. }
  111. if (qdd->size < shm_hdr_size) {
  112. dev_err(qdd->dev, "Shared memory size should greater than %d\n", shm_hdr_size);
  113. return 0;
  114. }
  115. user_valid_size = user_size - user_hdr_size;
  116. shm_valid_size = qdd->size - shm_hdr_size;
  117. return min(user_valid_size, shm_valid_size);
  118. }
  119. #if !IS_ENABLED(CONFIG_QCOM_VM_ALIVE_LOG_ENCRYPT)
  120. static int qcom_ddump_alive_log_to_shm(struct qcom_dmesg_dumper *qdd,
  121. u64 user_size)
  122. {
  123. size_t total_len, line_len;
  124. struct ddump_shm_hdr *hdr;
  125. u64 valid_size;
  126. void *base;
  127. total_len = 0;
  128. hdr = qdd->base;
  129. base = &hdr->data;
  130. valid_size = qcom_ddump_get_valid_size(qdd, user_size);
  131. if (valid_size < LOG_LINE_MAX)
  132. return -EINVAL;
  133. while ((total_len < valid_size - LOG_LINE_MAX) &&
  134. kmsg_dump_get_line(&qdd->iter, false, base, valid_size - total_len, &line_len) &&
  135. (line_len > 0)) {
  136. base = base + line_len;
  137. total_len = total_len + line_len;
  138. }
  139. hdr->svm_dump_len = total_len;
  140. return 0;
  141. }
  142. #endif /* !CONFIG_QCOM_VM_ALIVE_LOG_ENCRYPT */
  143. #else /* !CONFIG_ARCH_QTI_VM */
  144. static inline int qcom_ddump_alive_log_to_shm(struct qcom_dmesg_dumper *qdd,
  145. u64 user_size)
  146. {
  147. return 0;
  148. }
  149. #endif /* CONFIG_ARCH_QTI_VM */
  150. #endif /* _DMESG_DUMPER_PRIVATE_H */