Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for the Morello Coprocess Switcher for Purecap Kernels #1791

Open
wants to merge 3 commits into
base: cocalls
Choose a base branch
from

Conversation

paulmetzger
Copy link
Contributor

This fixes the user space switcher for coprocesses that purecap kernels provide on Morello. The least significant bit of the capability that is used to jump to the switcher code wasn't set, which meant that we left C64 mode. Besides that, the switcher used at two points in its code normal registers were it must use capability registers.
I've tested these fixes with the Stevie and Clocks example applications on a Morello board and in Qemu. I also fixed two Kyua test cases.

The cocalls branch, from which this branch is forked, is missing this fix: https://github.com/CTSRD-CHERI/cheribsd/pull/1378/files
I applied manually a fix based on this PR to my local copy of the wip_fix_morello_coproc_switcher_for_purecap_kernels branch to compile a purecap kernel that boots.

The least significant bit of the capability that points to the switcher needs
to be set. Otherwise, we leave C64 mode after jumping into the switcher with
BLRS. The switcher code of purecap kernels uses capability instructions and
attempting to execute these outside C64 mode results in an tag-violation error.

This commit also fixes two uses of non-capability instructions where the
switcher must use capabilties.
Cocall and coaccept expect the in- and output-buffers to be aligned to 16 bytes.
Asserts that check if inlen and outlen are also aligned fail in some test
cases. However, these checks seem unnecessary because both are function
parameters.
@paulmetzger paulmetzger requested a review from trasz August 11, 2023 13:41
* by purecap kernels uses capabilities and so fails if it is not
* executed in C64 mode.
*/
codecap_addr = cheri_getaddress(codecap);
Copy link
Member

@jrtc27 jrtc27 Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Use cheri_capmode, it’s target-independent
  2. Shouldn’t switcher_code_cap do this?
  3. This breaks for the vm_cocall_codecap case, because you add rather than or (IIRC cheri_capmode is idempotent) and so will double capmode
  4. Why is this based on kernel ABI? Surely it should always be purecap code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrtc27 I implemented these suggestions in this commit: b1ee348
I found more bugs in the coprocess implementation for Morello in the meantime. I have fixes for these and I'm hoping to find the time to add these to this PR soon.

@paulmetzger paulmetzger changed the title Wip fix morello coproc switcher for purecap kernels Fix for the Morello Coprocess Switcher for Purecap Kernels Aug 16, 2023
Set the cap mode bit in the code capability for the switcher code in
switcher_code_cap() like Jess suggested.
cheri_capmode() wasn't called in switcher_code_cap() when __aarch64__ is defined.
@@ -351,7 +351,11 @@ colocation_unborrow(struct thread *td)
if (!have_scb)
return;

#ifdef __CHERI_PURE_CAPABILITY__
peertd = scb.scb_borrower_td;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

KASSERT(peertd != td,
("%s: peertd %p == td %p\n", __func__, peertd, td));
#endif
KASSERT(peertd != td, ("%s: peertd %p == td %p\n", __func__, peertd, td));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

@@ -375,10 +379,13 @@ colocation_unborrow(struct thread *td)
#error "what architecture is this?"
#endif

#ifdef __CHERI_PURE_CAPABILITY__
KASSERT(td == scb.scb_td, ("%s: td %p != scb_td %p\n", __func__, td, (__cheri_fromcap struct thread *)scb.scb_td));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

@@ -539,7 +546,6 @@ setup_scb(struct thread *td)
int
sys__cosetup(struct thread *td, struct _cosetup_args *uap)
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh

@@ -556,14 +562,13 @@ switcher_code_cap(struct thread *td, ptraddr_t base, size_t length)
*/
codecap = cheri_capability_build_user_rwx(CHERI_CAP_USER_CODE_PERMS,
base, length, 0);
#ifndef __aarch64__
/*
* XXX: Somehow makes every attempt at ldr/str in the switcher
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely this is now not true?

@@ -616,6 +621,7 @@ kern_cosetup(struct thread *td, int what,
td->td_proc->p_sysent->sv_cocall_base,
td->td_proc->p_sysent->sv_cocall_len);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh

@@ -634,6 +640,7 @@ kern_cosetup(struct thread *td, int what,
td->td_proc->p_sysent->sv_coaccept_base,
td->td_proc->p_sysent->sv_coaccept_len);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh

}

ATF_TC_WITHOUT_HEAD(cocall);
ATF_TC_BODY(cocall, tc)
{
char *name;
uint64_t buf;
uint64_t buf __attribute__((aligned(16)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These all seem suspicious

@@ -110,14 +110,14 @@ wait_for_coregister(void)
*
* XXX: You might have been expecting something more clever.
*/
usleep(200000);
usleep(600000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blegh... can we just do something actually correct rather than bodging it more?

@@ -47,11 +47,11 @@ coaccept(void * __capability * __capability cookiep,

if (outbuf != NULL) {
assert(__builtin_is_aligned(outbuf, sizeof(void * __capability)));
assert(__builtin_is_aligned(outlen, sizeof(void * __capability)));
//assert(__builtin_is_aligned(outlen, sizeof(void * __capability)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can't be committed as commented-out code (and certainly not with the style-violating C-style comments)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants