Skip to content

Commit

Permalink
Merge pull request #104 from xitska/master
Browse files Browse the repository at this point in the history
Added documentation for base XVIO functionality
  • Loading branch information
tuxuser authored Sep 4, 2024
2 parents 9657aac + 86f975e commit 238d144
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/NAVIGATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
- development/dev-portal-api/**
- [XTF APIs](development/xtf-apis.md)
- development/xtf-apis/*.md
- [Xbox Virtual Input/Output](development/xvio/xvio-overview.md)
- development/xvio/*.md
- Ring Buffers
- development/xvio/ring-buffers/*.md
- Misc
- [Codenames](misc/codenames.md)
- [FAQ](faq.md)
41 changes: 41 additions & 0 deletions docs/development/xvio/ring-buffers/xvio-create-ring-buffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# XvioCreateRingBuffer function
Creates a ring buffer for passing large amounts of data between partitions. Interestingly, it seems to be used as an auxiliary XvioPostMessage in some cases, though the reason for this is unknown.

## Syntax
```cpp title='C++'
NTSTATUS XvioCreateRingBuffer(
uint32_t ContextId,
uint64_t TargetPartition,
uint16_t Unk1,
uint32_t ReceivePageCount,
uint32_t SendPageCount,
PXVIO_RING_BUFFER RingBuffer
);
```

## Parameters
`uint32_t ContextId`
The *[Context ID](../xvio-overview.md/#context-identifiers)* to communicate to on the remote partition.

`uint64_t TargetPartition`
Target partition for the ring buffer to be shared with. *See [partition identifiers](../xvio-overview.md/#partition-identifiers) for a list of partitions and their corresponding IDs.*

`uint16_t Unk1`
Not sure what this is, seems important though. Perhaps allocation type?

`uint32_t ReceivePageCount`
Amount of pages, used for reading data, to be allocated to the ring buffer.

`uint32_t SendPageCount`
Amount of pages, used for writing data, to be allocated to the ring buffer.

`PXVIO_RING_BUFFER RingBuffer`
Pointer to an **XVIO_RING_BUFFER** structure, used for output.

## Return value
Returns a generic **NTSTATUS** value.

## Under the microscope
Put simply, XvioCreateRingBuffer allocates a user-specified amount of contiguous physical pages. The guest physical address of these pages are then posted to HostOS, amongst other data, with the message code 0x5 - which I've chosen to name *RingBufferAction* as the same code is used when destroying a ring buffer. The local partition then waits for the Ring Buffer's synchronization event to be signalled (presumably by HostOS) before returning the Ring Buffer Context to the caller.

*Research into how HostOS handles a RingBufferAction is planned, I've just yet to get around to it :)*
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# XvioGetRingBufferContextSafe
Safe version of *[XvioGetRingBufferContext](./xvio-get-ring-buffer-context.md).* Essentially just checks if the XVIO context is initialized and the *ContextId* parameter matches the ring buffer's context ID.

## Syntax
```cpp title='C++'
PXVIO_RING_BUFFER XvioGetRingBufferContext(
uint32_t TargetPartition,
uint32_t ContextId
);
```

## Parameters
`uint32_t TargetPartition`
The *[Partition ID](../xvio-overview.md/#partition-identifiers)* of the partition the ring buffer targets.

`uint32_t ContextId`
The *[Context ID](../xvio-overview.md/#context-identifiers)* of the XVIO context the ring buffer targets.

## Return value
Returns a pointer to a **XVIO_RING_BUFFER** structure.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# XvioGetRingBufferContext function
One would assume this function returns a pointer to a ring buffer context but instead, this appears to always return 0? Thus, for getting a ring buffer context, *[XvioGetRingBufferContextSafe](./xvio-get-ring-buffer-context-safe.md)* should be used instead as it actually returns a pointer to the ring buffer context.

*Once I find any uses of XvioGetRingBufferContext in any drivers, I'll do a little research and update this page. But for now, this function shall remain a weird one.*
24 changes: 24 additions & 0 deletions docs/development/xvio/ring-buffers/xvio-read-ring-buffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# XvioReadRingBuffer function
Reads data from a ring buffer into a buffer

## Syntax
```cpp title='C++'
NTSTATUS XvioReadRingBuffer(
PXVIO_RING_BUFFER RingBuffer,
void* Buffer,
size_t* BytesRead
);
```

## Parameters
`PXVIO_RING_BUFFER`
Pointer to a ring buffer context. Can be retrieved with *[XvioGetRingBufferContext](./xvio-get-ring-buffer-context.md)* or *[XvioGetRingBufferContextSafe](./xvio-get-ring-buffer-context-safe.md).*

`void* Buffer`
Pointer to a buffer containing the data to be written.

`size_t* BytesRead`
Pointer to the amount of bytes to read. Also acts as the output for the amount of bytes read.

## Return value
Either returns `0x213`, `0x214`, or a standard **NTSTATUS**. I believe that `0x213` means there's still more data and that `0x214` means the end of the ring buffer was reached during a read. That being said, I'm not 100% certain on this information.
28 changes: 28 additions & 0 deletions docs/development/xvio/ring-buffers/xvio-write-ring-buffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# XvioWriteRingBuffer function
Writes to some data to a ring buffer.

## Syntax
```cpp title='C++'
NTSTATUS XvioWriteRingBuffer(
PXVIO_RING_BUFFER RingBuffer,
void* Buffer,
size_t Length,
void** Unk1
);
```

## Parameters
`PXVIO_RING_BUFFER RingBuffer`
Pointer to a ring buffer context. Can be retrieved with *[XvioGetRingBufferContext](./xvio-get-ring-buffer-context.md)* or *[XvioGetRingBufferContextSafe](./xvio-get-ring-buffer-context-safe.md).*

`void* Buffer`
Pointer to a buffer containing the data to be written.

`size_t Length`
Amount of bytes to be written from the user-specified buffer into the ring buffer.

`void** Unk1`
Unknown :/

## Return value
Returns a standard **NTSTATUS** value.
16 changes: 16 additions & 0 deletions docs/development/xvio/xvio-cleanup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# XvioCleanup function
Cleans up and frees an XVIO Context ID. Also destroys the allocated ring buffer, if one has been allocated.

## Syntax
```cpp title='C++'
NTSTATUS XvioCleanup(
uint32_t XvioContextId
);
```

## Parameters
`uint32_t XvioContextId`
The ID of the context to be cleaned up, same as the one created with *XvioInitialize.*

## Return value
Returns a generic **NTSTATUS** value.
10 changes: 10 additions & 0 deletions docs/development/xvio/xvio-get-current-partition-id.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# XvioGetCurrentPartitionId function
Returns the identifier number for the current partition, which is set by the driver during initialization.

## Syntax
```cpp title='C++'
uint64_t XvioGetCurrentPartitionId(void);
```
## Return value
The ID of the current partition, for reference see *[partition identifiers](./xvio-overview.md/#partition-identifiers).*
46 changes: 46 additions & 0 deletions docs/development/xvio/xvio-initialize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# XvioInitialize function
Initializes an XVIO Context with the requested ID.

## Syntax
```cpp title='C++'
NTSTATUS XvioInitialize(
uint32_t XvioContextId,
uint64_t TargetPartition,
uint64_t Unk1,
uint64_t Unk2,
void (*ReceiveMessageCallback)(
uint64_t XvioContextId,
uint64_t RemotePartition,
uint16_t MessageCode,
uint32_t DataSize,
void* Data
),
void* Callback2
);
```

## Parameters
`uint32_t XvioContextId`
The unique Context ID for the XVIO instances, acting as a unique identifier for the driver or a link to a remote driver. Do note that only one Context IDs are **unique** meaning two drivers (in the same partition) cannot allocate the same Context ID. It is also worth mentioning that the amount of available XVIO Contexts in a partition is **finite**, totalling **32** IDs. *For more detail, see [context identifiers](./xvio-overview.md/#context-identifiers).*

`uint64_t TargetPartition`
The target partition (*see [Partition IDs](./xvio-overview.md/#partition-identifiers)*) - *can be **0**, permitting communication with all remote partitions.*

`uint64_t Unk1`
Currently unknown ¯\\\_(ツ)_

`uint64_t Unk2`
Appears to be a shared structure of some description?

`void* ReceiveMessageCallback`
Pointer to a callback function which is called when a message is received from a *remote* partition. Practically the same function prototype as [XvioPostMessage](./xvio-post-message.md).

`void* Callback2`
Similar to `ReceiveMessageCallback` but doesn't seem to be specific to messages. It's possible that this is meant to be a callback to an error handler function, but I have yet to confirm this.

## Return value
Returns your standard **NTSTATUS** with some extra XVIO statuses added on top (will document these soon)

## Important notes
When called, *XvioInitialize* checks if the *XvioContextId* has already been initialized. In **most** cases, all context ID's are typically already in use within a partition, meaning a developer would likely have to hijack an XVIO context.
*Research into this is planned but is* **currently** *impossible, as fully hijacking XVIO contexts would likely require kernel function hooks for callback functions (in all applicable partitions)*
24 changes: 24 additions & 0 deletions docs/development/xvio/xvio-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Overview of XVIO
The *XVIO driver* (`xvio.sys`) facilitates all communication between the virtualized partitions. It's APIs share some similarity with the [Hyper-V Inter-Partition Communication](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/main/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v6.0b.pdf){:target='blank'} APIs. If you're interested in more details, this document should still apply to XVIO, atleast some-what.

Whilst each partition has it's own version of `xvio.sys`, the differences appear to be minor, as each driver is simply being built using different preprocessor definitions to target different partitions.

## Context identifiers
The context identifier is an ID that is unique to an instance of XVIO that is initialized using *[XvioInitialize](./xvio-initialize.md).* In total there are 32 unique identifiers available to a partition. This number is finite as all the contexts are stored within an array in `xvio.sys`'s data section, where contexts are allocated to drivers where needed.

You may find it helpful to think of a context ID as a driver ID. This is because when communicating between partitions, it is the context ID that specifies what driver (on the remote partition) to communicate with. For example, `xvmm.sys` *- the virtual machine manager on HostOS -* uses the context identifier `0xf`. Thus, to communicate with this driver, `xvmctrl.sys` *- the virtual machine control driver on SystemOS -* uses that same ID to send requests to the VM manager. Furthermore, for the sake of continuity, it is common for drivers with similar functionality to use the same context ID on different partitions, despite it not being strictly necessary from a functional stand-point. With this in mind, we can be certain that all drivers related to virtual machine management and control allocate the context ID `0xf` on their respective operating systems.

## Partition identifiers
A lot of the XVIO functions take a partition ID as an argument, allowing for IO with a specified partition. An enumeration outlining these IDs can be found below:
```cpp
enum PARTITION_ID {
Any = 0,
HostOS = 1,
SystemOS = 2,
GameOS = 3
};
```

## Very, very important disclaimer
This research is not complete! There's plenty more functions within the XVIO drivers that I simply haven't gotten around to analysing or documenting. For reference, there's around 67 exported functions (excluding DllInitialize and DllUnload) within `xviosra.sys`.
Oh and also, a lot of information may be missing or some information may seem abstract as we currently cannot know how the hypervisor is actually handling XVIO-related hypercalls. That being said I aim to add a bunch more info on how HostOS is handling things at a lower level! :)
32 changes: 32 additions & 0 deletions docs/development/xvio/xvio-post-message.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# XvioPostMessage function
Sends a message (asynchronously) to the target partition. The message is then handled by an *XVIO context* within one of the remote partition's drivers.

## Syntax
```cpp title='C++'
NTSTATUS XvioPostMessage(
uint32_t TargetContextId,
uint64_t TargetPartition,
uint64_t MessageCode,
uint16_t DataSize,
void* Data
);
```

## Parameters
`uint32_t TargetContextId`
The context ID of the target XVIO instance *(pretty much the target driver)* on the target partition.

`uint64_t TargetPartition`
Pretty self-explanatory, the partition the message is targeted to, be it HostOS, SystemOS or GameOS. *See [Partition IDs](./xvio-overview.md#partition-identifiers) for more details.*

`uint64_t MessageCode`
The code that is being posted, practically designating the action to be performed by the target.

`uint16_t DataSize`
Specifies the size of the *Data* buffer in bytes, with a maximum of 232 bytes total -- *can be 0.*

`void* Data`
Pointer to the data to be sent to the target -- *can be NULL.*

## Return value
Returns your standard **NTSTATUS** with some extra XVIO statuses added on top (will document these soon)
20 changes: 20 additions & 0 deletions docs/development/xvio/xvio-set-focus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# XvioSetFocus function
Used for setting to another partition. Likely used for switching between SystemOS and GameOS.
It's weird this function is implemented in `xvio.sys` rather than `xvmctrl.sys` as it simply just posts a message to the Xbox VM Manager.

## Syntax
```cpp title='C++'
NTSTATUS XvioSetFocus(
uint64_t TargetPartition
);
```

## Parameters
`uint64_t TargetPartition`
The target partition to focus. *See [partition identifiers](./xvio-overview.md/#partition-identifiers) for more info.*

## Return value
Returns a standard **NTSTATUS** value.

## Important notes
**Cannot** be called from GameOS, and will just return **STATUS_ACCESS_DENIED** if this is attempted.
6 changes: 6 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,9 @@ plugins:

markdown_extensions:
- pymdownx.magiclink
- attr_list
- pymdownx.highlight:
anchor_linenums: true
use_pygments: true
pygments_lang_class: true
- pymdownx.superfences

0 comments on commit 238d144

Please sign in to comment.