Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,18 @@ config INTEL_TDX_GUEST
memory contents and CPU state. TDX guests are protected from
some attacks from the VMM.

endif # HYPERVISOR_GUEST
config TYCHE_TD0
bool "Tyche Isolation Monitor - Guest Support"
depends on X86_64 && CPU_SUP_INTEL
depends on X86_X2APIC
select ARCH_HAS_CC_PLATFORM
select X86_MEM_ENCRYPT
help
Support running as a guest under Tyche. The X86_MEM_ENCRYPT is
enabled to make sure the mem_encrypt_init() is called and
correspondingly having a shared memory region for swiotlb

endif #HYPERVISOR_GUEST

source "arch/x86/Kconfig.cpu"

Expand Down
1 change: 1 addition & 0 deletions arch/x86/coco/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ CFLAGS_core.o += -fno-stack-protector
obj-y += core.o

obj-$(CONFIG_INTEL_TDX_GUEST) += tdx/
obj-$(CONFIG_TYCHE_TD0) += tyche/
21 changes: 21 additions & 0 deletions arch/x86/coco/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@
enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE;
static u64 cc_mask __ro_after_init;

static bool noinstr tyche_cc_platform_has(enum cc_attr attr)
{
switch (attr) {
case CC_ATTR_GUEST_MEM_ENCRYPT:
/* Tyche doesn't encrypt the guest memory, but we want the dma
* memory to be a shared memory region. Retrn true on this one
* will force the pci_swiotlb_detect() to use swiotlb (bounce
* buffer) on x86 */
case CC_ATTR_MEM_ENCRYPT:
/* Following the comment on CC_ATTR_GUEST_MEM_ENCRYPT: This
* option will force the mem_encrypt_init() to mark swiotlb as
* decrypted */
return true;
default:
return false;
}
}

static bool noinstr intel_cc_platform_has(enum cc_attr attr)
{
switch (attr) {
Expand Down Expand Up @@ -104,6 +122,8 @@ bool noinstr cc_platform_has(enum cc_attr attr)
return amd_cc_platform_has(attr);
case CC_VENDOR_INTEL:
return intel_cc_platform_has(attr);
case CC_VENDOR_TYCHE:
return tyche_cc_platform_has(attr);
default:
return false;
}
Expand All @@ -118,6 +138,7 @@ u64 cc_mkenc(u64 val)
*
* - for AMD, bit *set* means the page is encrypted
* - for AMD with vTOM and for Intel, *clear* means encrypted
* - for Tyche, no encryption is needed
*/
switch (cc_vendor) {
case CC_VENDOR_AMD:
Expand Down
1 change: 1 addition & 0 deletions arch/x86/coco/tyche/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-y += tyche.o
12 changes: 12 additions & 0 deletions arch/x86/coco/tyche/tyche.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#undef pr_fmt
#define pr_fmt(fmt) "tyche: " fmt

#include <linux/cpufeature.h>
#include <asm/coco.h>

void __init tyche_early_init(void)
{
cc_vendor = CC_VENDOR_TYCHE;

pr_info("Guest detected\n");
}
1 change: 1 addition & 0 deletions arch/x86/include/asm/coco.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum cc_vendor {
CC_VENDOR_NONE,
CC_VENDOR_AMD,
CC_VENDOR_INTEL,
CC_VENDOR_TYCHE,
};

extern enum cc_vendor cc_vendor;
Expand Down
10 changes: 10 additions & 0 deletions arch/x86/include/asm/tyche.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _ASM_X86_TYCHE_H
#define _ASM_X86_TYCHE_H

#ifdef CONFIG_TYCHE_TD0

void __init tyche_early_init(void);

#endif /* CONFIG_TYCHE_TD0 */

#endif
2 changes: 2 additions & 0 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <asm/trapnr.h>
#include <asm/sev.h>
#include <asm/tdx.h>
#include <asm/tyche.h>

/*
* Manage page tables very early on.
Expand Down Expand Up @@ -523,6 +524,7 @@ asmlinkage __visible void __init __noreturn x86_64_start_kernel(char * real_mode

/* Needed before cc_platform_has() can be used for TDX */
tdx_early_init();
tyche_early_init();

copy_bootdata(__va(real_mode_data));

Expand Down
2 changes: 2 additions & 0 deletions arch/x86/mm/ioremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size,
* In TDX guests, memory is marked private by default. If encryption
* is not requested (using encrypted), explicitly set decrypt
* attribute in all IOREMAPPED memory.
* For Tyche guests, we are not going to encrypt the page and we skip
* the case inside cc_mkenc and cc_mkdec
*/
prot = PAGE_KERNEL_IO;
if ((io_desc.flags & IORES_MAP_ENCRYPTED) || encrypted)
Expand Down
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ source "drivers/vlynq/Kconfig"

source "drivers/virt/Kconfig"

source "drivers/tyche/Kconfig"

source "drivers/virtio/Kconfig"

source "drivers/vdpa/Kconfig"
Expand Down
2 changes: 2 additions & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,6 @@ obj-$(CONFIG_HTE) += hte/
obj-$(CONFIG_DRM_ACCEL) += accel/
obj-$(CONFIG_CDX_BUS) += cdx/

obj-$(CONFIG_DPLL) += dpll/
obj-$(CONFIG_S390) += s390/
obj-$(CONFIG_TYCHE_DRIVER) += tyche/
8 changes: 8 additions & 0 deletions drivers/tyche/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.order
*.ko
*.mod.c
*.mod.o
*.o
*.symvers
*.mod
*.cmd
10 changes: 10 additions & 0 deletions drivers/tyche/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Virtualization support drivers
#

config TYCHE_DRIVER
tristate "Tyche Isolation Monitor driver"
help
Say Y here to enable the tyche isolation monitor non-root ring 0 dirver

17 changes: 17 additions & 0 deletions drivers/tyche/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for Tyche driver
#

TARGET_MODULE:=tyche

ccflags-y += -I $(srctree)/drivers/tyche/include
ccflags-y += -I $(srctree)/drivers/tyche/libraries/common/include
ccflags-y += -I $(srctree)/drivers/tyche/libraries/dll/include
ccflags-y += -I $(srctree)/drivers/tyche/libraries/pts/include
ccflags-y += -I $(srctree)/drivers/tyche/libraries/capabilities/include

obj-y += $(TARGET_MODULE).o
$(TARGET_MODULE)-objs += src/driver.o src/ioctl.o src/domains.o src/capabilities.o
$(TARGET_MODULE)-objs += libraries/pts/src/lib.o libraries/pts/src/x86_64_pt.o
$(TARGET_MODULE)-objs += libraries/capabilities/src/ecs.o libraries/capabilities/src/lib.o libraries/capabilities/src/tyche_api.o
133 changes: 133 additions & 0 deletions drivers/tyche/include/domains.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#ifndef __SRC_DOMAINS_H__
#define __SRC_DOMAINS_H__

#include <linux/fs.h>
#include <linux/mm_types.h>

#include "dll.h"
#include "tyche_capabilities_types.h"
#define _IN_MODULE
#include "tyche_driver.h"
#undef _IN_MODULE

// ————————————————————————————————— Types —————————————————————————————————— //

#define UNINIT_USIZE (~((usize)0))
#define UNINIT_DOM_ID (~((domain_id_t)0))

/// Describes an domain's memory segment in user process address space.
typedef struct segment_t {
/// Start of the virtual memory segment.
usize vstart;

/// Size of the memory segment.
usize size;

/// Protection flags.
memory_access_right_t flags;

/// Type for the region: {Shared|Confidential}.
segment_type_t tpe;

/// Segments are stored in a double linked list.
dll_elem(struct segment_t, list);
} segment_t;

/// An entry point on a core for the domain.
typedef struct entry_t {
usize cr3;
usize rip;
usize rsp;
} entry_t;

/// All entry points for the domain.
typedef struct entries_t {
/// One entry per core, total number of entries.
size_t size;
/// The entries dynamically allocated.
entry_t *entries;
} entries_t;

/// Describes an domain.
typedef struct driver_domain_t {
/// The creator task's pid.
pid_t pid;

/// The domain's handle within the driver.
domain_handle_t handle;

/// The domain's domain id.
domain_id_t domain_id;

/// The start of the domain's physical contiguous memory region.
usize phys_start;

/// The start of the domain's virtual memory region in the untrusted process.
usize virt_start;

/// The size of the domain's contiguous memory region.
usize size;

/// The domain's traps.
usize traps;

/// The domain's core map.
usize cores;

/// The domain's permission.
usize perm;

/// The domain's switch value.
usize switch_type;

/// The domain's entry points per core.
entries_t entries;

/// The segments for the domain.
dll_list(segment_t, segments);

/// Domains are stored in a global list by the driver.
dll_elem(struct driver_domain_t, list);
} driver_domain_t;

// ———————————————————————————————— Helpers ————————————————————————————————— //

// Find a currently active domain from a file descriptor.
driver_domain_t *find_domain(domain_handle_t handle);

// ——————————————————————————————— Functions ———————————————————————————————— //

/// Initializes the driver.
void driver_init_domains(void);
/// Initializes the capability library.
int driver_init_capabilities(void);
/// Create a new domain with handle.
/// If ptr is not null, it points to the newly created driver domain.
int driver_create_domain(domain_handle_t handle, driver_domain_t **ptr);
/// Handles an mmap call to the driver.
/// This reserves a contiguous region and registers it until a domain claims it.
int driver_mmap_segment(driver_domain_t *domain, struct vm_area_struct *vma);
/// Returns the domain's physoffset.
/// We expect the handle to be valid, and the virtaddr to exist in segments.
int driver_get_physoffset_domain(driver_domain_t *domain, usize *phys_offset);
/// Sets up access rights and conf|share for the segment.
int driver_mprotect_domain(driver_domain_t *domain, usize vstart, usize size,
memory_access_right_t flags, segment_type_t tpe);
/// Register the trap bitmap for the domain.
int driver_set_traps(driver_domain_t *domain, usize traps);
/// Register the core map for the domain.
int driver_set_cores(driver_domain_t *domain, usize core_map);
/// Register the perm for the domain.
int driver_set_perm(driver_domain_t *domain, usize perm);
/// Register the switch_type for the domain.
int driver_set_switch(driver_domain_t *domain, usize sw);
/// Set the entry point on a core.
int driver_set_entry_on_core(driver_domain_t *domain, usize core, usize cr3,
usize rip, usize rsp);
/// Commits the domain. This is where the capability operations are done.
int driver_commit_domain(driver_domain_t *domain);
/// Implements the transition into a domain.
int driver_switch_domain(driver_domain_t *domain, void *args);
/// Delete the domain and revoke the capabilities.
int driver_delete_domain(driver_domain_t *domain);
#endif /*__SRC_DOMAINS_H__*/
Loading