Commit 4ac39c59 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86_urgent_for_v6.3_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:
 "There's a little bit more 'movement' in there for my taste but it
  needs to happen and should make the code better after it.

   - Check cmdline_find_option()'s return value before further
     processing

   - Clear temporary storage in the resctrl code to prevent access to an
     unexistent MSR

   - Add a simple throttling mechanism to protect the hypervisor from
     potentially malicious SEV guests issuing requests in rapid
     succession.

     In order to not jeopardize the sanity of everyone involved in
     maintaining this code, the request issuing side has received a
     cleanup, split in more or less trivial, small and digestible
     pieces. Otherwise, the code was threatening to become an
     unmaintainable mess.

     Therefore, that cleanup is marked indirectly also for stable so
     that there's no differences between the upstream code and the
     stable variant when it comes down to backporting more there"

* tag 'x86_urgent_for_v6.3_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm: Fix use of uninitialized buffer in sme_enable()
  x86/resctrl: Clear staged_config[] before and after it is used
  virt/coco/sev-guest: Add throttling awareness
  virt/coco/sev-guest: Convert the sw_exit_info_2 checking to a switch-case
  virt/coco/sev-guest: Do some code style cleanups
  virt/coco/sev-guest: Carve out the request issuing logic into a helper
  virt/coco/sev-guest: Remove the disable_vmpck label in handle_guest_request()
  virt/coco/sev-guest: Simplify extended guest request handling
  virt/coco/sev-guest: Check SEV_SNP attribute at probe time
parents 995bba43 cbebd68f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -128,8 +128,9 @@ struct snp_psc_desc {
	struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY];
} __packed;

/* Guest message request error code */
/* Guest message request error codes */
#define SNP_GUEST_REQ_INVALID_LEN	BIT_ULL(32)
#define SNP_GUEST_REQ_ERR_BUSY		BIT_ULL(33)

#define GHCB_MSR_TERM_REQ		0x100
#define GHCB_MSR_TERM_REASON_SET_POS	12
+2 −5
Original line number Diff line number Diff line
@@ -368,7 +368,6 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
{
	struct resctrl_schema *s;
	struct rdtgroup *rdtgrp;
	struct rdt_domain *dom;
	struct rdt_resource *r;
	char *tok, *resname;
	int ret = 0;
@@ -397,10 +396,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
		goto out;
	}

	list_for_each_entry(s, &resctrl_schema_all, list) {
		list_for_each_entry(dom, &s->res->domains, list)
			memset(dom->staged_config, 0, sizeof(dom->staged_config));
	}
	rdt_staged_configs_clear();

	while ((tok = strsep(&buf, "\n")) != NULL) {
		resname = strim(strsep(&tok, ":"));
@@ -445,6 +441,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
	}

out:
	rdt_staged_configs_clear();
	rdtgroup_kn_unlock(of->kn);
	cpus_read_unlock();
	return ret ?: nbytes;
+1 −0
Original line number Diff line number Diff line
@@ -555,5 +555,6 @@ void __check_limbo(struct rdt_domain *d, bool force_free);
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
void __init thread_throttle_mode_init(void);
void __init mbm_config_rftype_init(const char *config);
void rdt_staged_configs_clear(void);

#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
+21 −4
Original line number Diff line number Diff line
@@ -78,6 +78,19 @@ void rdt_last_cmd_printf(const char *fmt, ...)
	va_end(ap);
}

void rdt_staged_configs_clear(void)
{
	struct rdt_resource *r;
	struct rdt_domain *dom;

	lockdep_assert_held(&rdtgroup_mutex);

	for_each_alloc_capable_rdt_resource(r) {
		list_for_each_entry(dom, &r->domains, list)
			memset(dom->staged_config, 0, sizeof(dom->staged_config));
	}
}

/*
 * Trivial allocator for CLOSIDs. Since h/w only supports a small number,
 * we can keep a bitmap of free CLOSIDs in a single integer.
@@ -3107,7 +3120,9 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
{
	struct resctrl_schema *s;
	struct rdt_resource *r;
	int ret;
	int ret = 0;

	rdt_staged_configs_clear();

	list_for_each_entry(s, &resctrl_schema_all, list) {
		r = s->res;
@@ -3119,20 +3134,22 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
		} else {
			ret = rdtgroup_init_cat(s, rdtgrp->closid);
			if (ret < 0)
				return ret;
				goto out;
		}

		ret = resctrl_arch_update_domains(r, rdtgrp->closid);
		if (ret < 0) {
			rdt_last_cmd_puts("Failed to initialize allocations\n");
			return ret;
			goto out;
		}

	}

	rdtgrp->mode = RDT_MODE_SHAREABLE;

	return 0;
out:
	rdt_staged_configs_clear();
	return ret;
}

static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
+17 −9
Original line number Diff line number Diff line
@@ -2183,9 +2183,6 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned
	struct ghcb *ghcb;
	int ret;

	if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
		return -ENODEV;

	if (!fw_err)
		return -EINVAL;

@@ -2212,15 +2209,26 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned
	if (ret)
		goto e_put;

	if (ghcb->save.sw_exit_info_2) {
		/* Number of expected pages are returned in RBX */
		if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
		    ghcb->save.sw_exit_info_2 == SNP_GUEST_REQ_INVALID_LEN)
			input->data_npages = ghcb_get_rbx(ghcb);

	*fw_err = ghcb->save.sw_exit_info_2;
	switch (*fw_err) {
	case 0:
		break;

	case SNP_GUEST_REQ_ERR_BUSY:
		ret = -EAGAIN;
		break;

	case SNP_GUEST_REQ_INVALID_LEN:
		/* Number of expected pages are returned in RBX */
		if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST) {
			input->data_npages = ghcb_get_rbx(ghcb);
			ret = -ENOSPC;
			break;
		}
		fallthrough;
	default:
		ret = -EIO;
		break;
	}

e_put:
Loading