process_capability.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <bitset>
  6. #include "common/common_types.h"
  7. union ResultCode;
  8. namespace Kernel {
  9. class VMManager;
  10. /// The possible types of programs that may be indicated
  11. /// by the program type capability descriptor.
  12. enum class ProgramType {
  13. SysModule,
  14. Application,
  15. Applet,
  16. };
  17. /// Handles kernel capability descriptors that are provided by
  18. /// application metadata. These descriptors provide information
  19. /// that alters certain parameters for kernel process instance
  20. /// that will run said application (or applet).
  21. ///
  22. /// Capabilities are a sequence of flag descriptors, that indicate various
  23. /// configurations and constraints for a particular process.
  24. ///
  25. /// Flag types are indicated by a sequence of set low bits. E.g. the
  26. /// types are indicated with the low bits as follows (where x indicates "don't care"):
  27. ///
  28. /// - Priority and core mask : 0bxxxxxxxxxxxx0111
  29. /// - Allowed service call mask: 0bxxxxxxxxxxx01111
  30. /// - Map physical memory : 0bxxxxxxxxx0111111
  31. /// - Map IO memory : 0bxxxxxxxx01111111
  32. /// - Interrupts : 0bxxxx011111111111
  33. /// - Application type : 0bxx01111111111111
  34. /// - Kernel version : 0bx011111111111111
  35. /// - Handle table size : 0b0111111111111111
  36. /// - Debugger flags : 0b1111111111111111
  37. ///
  38. /// These are essentially a bit offset subtracted by 1 to create a mask.
  39. /// e.g. The first entry in the above list is simply bit 3 (value 8 -> 0b1000)
  40. /// subtracted by one (7 -> 0b0111)
  41. ///
  42. /// An example of a bit layout (using the map physical layout):
  43. /// <example>
  44. /// The MapPhysical type indicates a sequence entry pair of:
  45. ///
  46. /// [initial, memory_flags], where:
  47. ///
  48. /// initial:
  49. /// bits:
  50. /// 7-24: Starting page to map memory at.
  51. /// 25 : Indicates if the memory should be mapped as read only.
  52. ///
  53. /// memory_flags:
  54. /// bits:
  55. /// 7-20 : Number of pages to map
  56. /// 21-25: Seems to be reserved (still checked against though)
  57. /// 26 : Whether or not the memory being mapped is IO memory, or physical memory
  58. /// </example>
  59. ///
  60. class ProcessCapabilities {
  61. public:
  62. using InterruptCapabilities = std::bitset<1024>;
  63. using SyscallCapabilities = std::bitset<128>;
  64. ProcessCapabilities() = default;
  65. ProcessCapabilities(const ProcessCapabilities&) = delete;
  66. ProcessCapabilities(ProcessCapabilities&&) = default;
  67. ProcessCapabilities& operator=(const ProcessCapabilities&) = delete;
  68. ProcessCapabilities& operator=(ProcessCapabilities&&) = default;
  69. /// Initializes this process capabilities instance for a kernel process.
  70. ///
  71. /// @param capabilities The capabilities to parse
  72. /// @param num_capabilities The number of capabilities to parse.
  73. /// @param vm_manager The memory manager to use for handling any mapping-related
  74. /// operations (such as mapping IO memory, etc).
  75. ///
  76. /// @returns RESULT_SUCCESS if this capabilities instance was able to be initialized,
  77. /// otherwise, an error code upon failure.
  78. ///
  79. ResultCode InitializeForKernelProcess(const u32* capabilities, std::size_t num_capabilities,
  80. VMManager& vm_manager);
  81. /// Initializes this process capabilities instance for a userland process.
  82. ///
  83. /// @param capabilities The capabilities to parse.
  84. /// @param num_capabilities The total number of capabilities to parse.
  85. /// @param vm_manager The memory manager to use for handling any mapping-related
  86. /// operations (such as mapping IO memory, etc).
  87. ///
  88. /// @returns RESULT_SUCCESS if this capabilities instance was able to be initialized,
  89. /// otherwise, an error code upon failure.
  90. ///
  91. ResultCode InitializeForUserProcess(const u32* capabilities, std::size_t num_capabilities,
  92. VMManager& vm_manager);
  93. /// Initializes this process capabilities instance for a process that does not
  94. /// have any metadata to parse.
  95. ///
  96. /// This is necessary, as we allow running raw executables, and the internal
  97. /// kernel process capabilities also determine what CPU cores the process is
  98. /// allowed to run on, and what priorities are allowed for threads. It also
  99. /// determines the max handle table size, what the program type is, whether or
  100. /// not the process can be debugged, or whether it's possible for a process to
  101. /// forcibly debug another process.
  102. ///
  103. /// Given the above, this essentially enables all capabilities across the board
  104. /// for the process. It allows the process to:
  105. ///
  106. /// - Run on any core
  107. /// - Use any thread priority
  108. /// - Use the maximum amount of handles a process is allowed to.
  109. /// - Be debuggable
  110. /// - Forcibly debug other processes.
  111. ///
  112. /// Note that this is not a behavior that the kernel allows a process to do via
  113. /// a single function like this. This is yuzu-specific behavior to handle
  114. /// executables with no capability descriptors whatsoever to derive behavior from.
  115. /// It being yuzu-specific is why this is also not the default behavior and not
  116. /// done by default in the constructor.
  117. ///
  118. void InitializeForMetadatalessProcess();
  119. /// Gets the allowable core mask
  120. u64 GetCoreMask() const {
  121. return core_mask;
  122. }
  123. /// Gets the allowable priority mask
  124. u64 GetPriorityMask() const {
  125. return priority_mask;
  126. }
  127. /// Gets the SVC access permission bits
  128. const SyscallCapabilities& GetServiceCapabilities() const {
  129. return svc_capabilities;
  130. }
  131. /// Gets the valid interrupt bits.
  132. const InterruptCapabilities& GetInterruptCapabilities() const {
  133. return interrupt_capabilities;
  134. }
  135. /// Gets the program type for this process.
  136. ProgramType GetProgramType() const {
  137. return program_type;
  138. }
  139. private:
  140. /// Attempts to parse a given sequence of capability descriptors.
  141. ///
  142. /// @param capabilities The sequence of capability descriptors to parse.
  143. /// @param num_capabilities The number of descriptors within the given sequence.
  144. /// @param vm_manager The memory manager that will perform any memory
  145. /// mapping if necessary.
  146. ///
  147. /// @return RESULT_SUCCESS if no errors occur, otherwise an error code.
  148. ///
  149. ResultCode ParseCapabilities(const u32* capabilities, std::size_t num_capabilities,
  150. VMManager& vm_manager);
  151. /// Attempts to parse a capability descriptor that is only represented by a
  152. /// single flag set.
  153. ///
  154. /// @param set_flags Running set of flags that are used to catch
  155. /// flags being initialized more than once when they shouldn't be.
  156. /// @param set_svc_bits Running set of bits representing the allowed supervisor calls mask.
  157. /// @param flag The flag to attempt to parse.
  158. /// @param vm_manager The memory manager that will perform any memory
  159. /// mapping if necessary.
  160. ///
  161. /// @return RESULT_SUCCESS if no errors occurred, otherwise an error code.
  162. ///
  163. ResultCode ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag,
  164. VMManager& vm_manager);
  165. /// Clears the internal state of this process capability instance. Necessary,
  166. /// to have a sane starting point due to us allowing running executables without
  167. /// configuration metadata. We assume a process is not going to have metadata,
  168. /// and if it turns out that the process does, in fact, have metadata, then
  169. /// we attempt to parse it. Thus, we need this to reset data members back to
  170. /// a good state.
  171. ///
  172. /// DO NOT ever make this a public member function. This isn't an invariant
  173. /// anything external should depend upon (and if anything comes to rely on it,
  174. /// you should immediately be questioning the design of that thing, not this
  175. /// class. If the kernel itself can run without depending on behavior like that,
  176. /// then so can yuzu).
  177. ///
  178. void Clear();
  179. /// Handles flags related to the priority and core number capability flags.
  180. ResultCode HandlePriorityCoreNumFlags(u32 flags);
  181. /// Handles flags related to determining the allowable SVC mask.
  182. ResultCode HandleSyscallFlags(u32& set_svc_bits, u32 flags);
  183. /// Handles flags related to mapping physical memory pages.
  184. ResultCode HandleMapPhysicalFlags(u32 flags, u32 size_flags, VMManager& vm_manager);
  185. /// Handles flags related to mapping IO pages.
  186. ResultCode HandleMapIOFlags(u32 flags, VMManager& vm_manager);
  187. /// Handles flags related to the interrupt capability flags.
  188. ResultCode HandleInterruptFlags(u32 flags);
  189. /// Handles flags related to the program type.
  190. ResultCode HandleProgramTypeFlags(u32 flags);
  191. /// Handles flags related to the handle table size.
  192. ResultCode HandleHandleTableFlags(u32 flags);
  193. /// Handles flags related to the kernel version capability flags.
  194. ResultCode HandleKernelVersionFlags(u32 flags);
  195. /// Handles flags related to debug-specific capabilities.
  196. ResultCode HandleDebugFlags(u32 flags);
  197. SyscallCapabilities svc_capabilities;
  198. InterruptCapabilities interrupt_capabilities;
  199. u64 core_mask = 0;
  200. u64 priority_mask = 0;
  201. u32 handle_table_size = 0;
  202. u32 kernel_version = 0;
  203. ProgramType program_type = ProgramType::SysModule;
  204. bool is_debuggable = false;
  205. bool can_force_debug = false;
  206. };
  207. } // namespace Kernel