GVM User Suite
User tools for the GVM open source project.
NVIDIA API Test

In order to properly test the device's interaction with the RM Core on the server. The components of the RM API that we implemented in the GVM suite are the following:

API Implemented

  1. NV_CREATE_OS_EVENT - Creates an operating system event.
  2. NV_VERSION_CHECK - Performs the RM API version check.
  3. NV_ALLOC_RES - Allocates a resource/client on the system.
  4. NV_FREE_RES - Frees a resource/client on the system.
  5. NV_CONTROL_RES - Sends a simple control command for a specific resource/client on the system.

These API implementations, allow us to implement the vast majority of the GVM user suite required to provide mediated devices to individuals using the GVM management layers.

Tests

To ensure we can correctly handle the entire system, we developed several tests to ensure all components of the RM API which we use functions correctly:

  1. NV_VERSION_CHECK Tests
    1. RM Version Check Ok - Checks if we can handle the correct version check for the RMCore.
    2. RM Version Check Incorrect - Checks if we can handle the incorrect version check for the RMCore.
    3. RM Version Check Ignore - Checks if we can handle the ignore version check for the RMCore.
  2. NV_ALLOC_RES Tests
    1. Allocates a Client ID. - Checks if we can correctly allocate a root.
    2. Allocates a Client ID (Invalid FD) - Checks if we can correctly fail on allocating a root.
    3. Allocates a Client ID (Bad FD) - Checks if we can correctly fail on allocating a root.
    4. Allocates a Client Id (Bad Argument) - Checks if we can correctly fail on allocating a root.
  3. NV_FREE_RES Tests
    1. Deallocates a Client ID. - Checks if we can correctly deallocate a root object.
    2. Deallocates a Client ID (Invalid FD) - Checks if we can correctly fail on deallocating a root.
    3. Double Deallocation Root - Checks if we can correctly fail on double deallocating a root.
  4. NV_CONTROL_RES Tests
    1. Gets The Probed IDs - Determines if we can get the probed ids correctly.

Version Check Tests

These sections determines if the version check of the RM Core is handled correctly.

RM Version Check Ok

This code determines if a correct RM Version number works on the system. The corresponding pseudo-code is as follows:

rm_version_check(nvctl_file, false, RM_VERSION)
uint8_t rm_version_check(int ctl_fd, uint8_t ignore_version, const char *version)
Version check for the RM API.
Definition: api.c:39

RM Version Check Incorrect

This code determines if an incorrect RM Version number works on the system. The corresponding pseudo-code is as follows:

rm_version_check(nvctl_file, false, NULL)

RM Version Check Ignore

This code determines if an ignored RM Version number works on the system. The corresponding pseudo-code is as follows:

rm_version_check(nvctl_file, true, NULL)

Alloc Root Tests

These tests determine if we can correctly allocate client ids.

Allocates a Client ID.

This code determines if we can correctly allocate a device client id for a control file. The corresponding pseudo-code is as follows:

rm_alloc_res(ctlfd, NULL, 0, 0, NULL) != NULL
struct NvResource * rm_alloc_res(int fd, struct NvResource *parent, uint32_t object, uint32_t rm_class, void *data)
Allocates a Node for a resource.
Definition: api.c:65

Allocates a Client ID (Invalid FD)

This code determines if we can correctly fail given an invalid FD. The corresponding pseudo-code is as follows:

rm_alloc_res(-1, NULL, 0, 0, NULL) == NULL

Allocates a Client ID (Bad FD)

This code determines if we can correctly fail given an bad FD. The corresponding pseudo-code is as follows:

rm_alloc_res(STDOUT_FILENO, NULL, 0, 0, NULL) == NULL

Allocates a Client Id (Bad Argument)

This code determines if we can correctly fail given an bad argument. The corresponding pseudo-code is as follows:

rm_alloc_res(ctlfd, NULL, 0, 0xA080, NULL) == NULL

Free Root Tests

These tests verify we can correctly free the client ids when necessary.

Deallocates a Client ID.

This code determines if we can correctly deallocate a device client id for a control file. The corresponding pseudo-code is as follows:

rm_free_res(ctlfd, resource)
uint8_t rm_free_res(int fd, struct NvResource *object)
Frees a Node for a Resource.
Definition: api.c:124

Deallocates a Client ID (Invalid FD)

This code determines if we can correctly fail given an invalid FD. The corresponding pseudo-code is as follows:

rm_free_res(-1, object) == 0

Double Deallocation Root

This code determines if we properly handle if a resource will be doubly deallocated. The corresponding pseudo-code is:

rm_free_res(ctlfd, resource) && !rm_free_res(ctlfd, resource)

Control Tests

These tests verify we can correctly control a particular gpu object.

Gets The Probed IDs

This code ensures we can get the probed device ids that are present in the NVIDIA kernel module correctly in the user program. The corresponding pseudo-code is:

RM_CTRL(ctlfd, ptr, NV0000_GET_PROBED_IDS, probed_ids) != NULL && probed_ids.gpu_ids[0] != 0xFFFFFFFF
#define RM_CTRL(fd, res, cmd, data)
Controls a RM Resource.
Definition: api.h:133
#define NV0000_GET_PROBED_IDS
Command for rm control res to get a list of all probed ids.
Definition: nv0000.h:29