Re: [RFC v2 11/13] keys/mktme: Program memory encryption keys on a system wide basis
From: Peter Zijlstra <peterz@infradead.org>
Date: 2018-12-04 09:21:53
Also in:
keyrings, linux-mm
On Mon, Dec 03, 2018 at 11:39:58PM -0800, Alison Schofield wrote:
+struct mktme_hw_program_info {
+ struct mktme_key_program *key_program;
+ unsigned long status;
+};
+
+/* Program a KeyID on a single package. */
+static void mktme_program_package(void *hw_program_info)
+{
+ struct mktme_hw_program_info *info = hw_program_info;
+ int ret;
+
+ ret = mktme_key_program(info->key_program);
+ if (ret != MKTME_PROG_SUCCESS)
+ WRITE_ONCE(info->status, ret);What's the purpose of that WRITE_ONCE()?
quoted hunk ↗ jump to hunk
+} + +/* Program a KeyID across the entire system. */ +static int mktme_program_system(struct mktme_key_program *key_program, + cpumask_var_t mktme_cpumask) +{ + struct mktme_hw_program_info info = { + .key_program = key_program, + .status = MKTME_PROG_SUCCESS, + }; + get_online_cpus(); + on_each_cpu_mask(mktme_cpumask, mktme_program_package, &info, 1); + put_online_cpus(); + + return info.status; +} + /* Copy the payload to the HW programming structure and program this KeyID */ static int mktme_program_keyid(int keyid, struct mktme_payload *payload) {@@ -84,7 +116,7 @@ static int mktme_program_keyid(int keyid, struct mktme_payload *payload) kprog->key_field_2[i] ^= kern_entropy[i]; } } - ret = mktme_key_program(kprog); + ret = mktme_program_system(kprog, mktme_leadcpus); kmem_cache_free(mktme_prog_cache, kprog); return ret; }@@ -299,6 +331,28 @@ struct key_type key_type_mktme = { .destroy = mktme_destroy_key, }; +static int mktme_build_leadcpus_mask(void) +{ + int online_cpu, mktme_cpu; + int online_pkgid, mktme_pkgid = -1; + + if (!zalloc_cpumask_var(&mktme_leadcpus, GFP_KERNEL)) + return -ENOMEM; + + for_each_online_cpu(online_cpu) { + online_pkgid = topology_physical_package_id(online_cpu); + + for_each_cpu(mktme_cpu, mktme_leadcpus) { + mktme_pkgid = topology_physical_package_id(mktme_cpu); + if (mktme_pkgid == online_pkgid) + break; + } + if (mktme_pkgid != online_pkgid) + cpumask_set_cpu(online_cpu, mktme_leadcpus);
Do you really need LOCK prefixed bit set here?
+ } + return 0; +}
How is that serialized and kept relevant in the face of hotplug? Also, do you really need O(n^2) to find the first occurence of a value in an array?