Skip to content

Drivers: hv: hv_common: use meaningful errnos for hypercall statuses#147

Open
hargar19 wants to merge 1 commit into
project/hcl-dev/6.18from
user/hargar/6.18-hv-status-errno-fix-dev
Open

Drivers: hv: hv_common: use meaningful errnos for hypercall statuses#147
hargar19 wants to merge 1 commit into
project/hcl-dev/6.18from
user/hargar/6.18-hv-status-errno-fix-dev

Conversation

@hargar19

Copy link
Copy Markdown
Collaborator

Several HV_STATUS_* codes were collapsed to -EIO in commit 3817854 ("hyperv: Log hypercall status codes as strings") when hv_result_to_errno() was converted from a switch statement to a table-driven lookup. The change was a side-effect of consolidating string/errno mappings into one place; the commit message focused on adding hv_status_printk() for debugging.

The previous mapping in hv_status_to_errno() (used in OHCL v6.12 and earlier) preserved more meaningful errnos for several codes that have natural POSIX counterparts. The collapse to -EIO loses information at call sites that key behavior on the converted errno (for example mshv_vtl_configure_reg_page() whitelists -EINVAL/-EACCES to fall back gracefully when the host refuses to install the register-page overlay; with -EIO that call site now hits a BUG()).

Restore the semantically meaningful mappings for the affected statuses:

Hyper-V Status Old errno New errno
HV_STATUS_ACCESS_DENIED -EIO -EACCES
HV_STATUS_OPERATION_DENIED -EIO -EACCES
HV_STATUS_UNKNOWN_PROPERTY -EIO -EINVAL
HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE -EIO -EINVAL
HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED -EIO -EOPNOTSUPP

EACCES is the canonical errno for permission denied, EINVAL for invalid argument, and EOPNOTSUPP for unsupported operations. These mappings match both their <errno.h> definitions and the established meanings in the v6.12 mapping.

Also drop two duplicate _STATUS_INFO() rows for HV_STATUS_INVALID_LP_INDEX and HV_STATUS_INVALID_REGISTER_VALUE that were leftover from the original table conversion.

Signed-off-by: Hardik Garg hargar@microsoft.com

Several HV_STATUS_* codes were collapsed to -EIO in commit 3817854
("hyperv: Log hypercall status codes as strings") when hv_result_to_errno()
was converted from a switch statement to a table-driven lookup. The change
was a side-effect of consolidating string/errno mappings into one place;
the commit message focused on adding hv_status_printk() for debugging.

The previous OOT helper hv_status_to_errno() (in v6.12) preserved more
meaningful errnos for several codes that have natural POSIX counterparts.
The collapse-to-EIO loses information at call sites that key behavior on
the converted errno (for example mshv_vtl_configure_reg_page() whitelists
-EINVAL/-EACCES to fall back gracefully when the host refuses to install
the register-page overlay; with -EIO that call site now hits a BUG()).

Restore the semantically meaningful mappings for the affected statuses:

  HV_STATUS_ACCESS_DENIED                    -EIO  -> -EACCES
  HV_STATUS_OPERATION_DENIED                 -EIO  -> -EACCES
  HV_STATUS_UNKNOWN_PROPERTY                 -EIO  -> -EINVAL
  HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE      -EIO  -> -EINVAL
  HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED  -EIO  -> -EOPNOTSUPP

EACCES is the canonical errno for permission denied, EINVAL for invalid
argument, and EOPNOTSUPP for unsupported operations. These mappings match
both their <errno.h> definitions and the established meanings in the OOT
v6.12 helper.

Also drop two duplicate _STATUS_INFO() rows for HV_STATUS_INVALID_LP_INDEX
and HV_STATUS_INVALID_REGISTER_VALUE that were leftover from the original
table conversion. find_hv_status_info() is first-match-wins so the dead
rows were not reachable, but they are confusing on review.

Impact analysis
---------------

The change only matters at sites that distinguish between specific errnos
(e.g. `ret == -EIO` vs `ret == -EACCES`). To confirm safety, the entire
kernel tree was audited for equality comparisons against any of the
affected errnos in Hyper-V-touching code:

  $ git grep -nE '(ret|status|err|rc|r)[[:space:]]*==[[:space:]]*\
        -(EACCES|EBADFD|ENOTRECOVERABLE|EOPNOTSUPP|EIO|EINVAL|ENOMEM)' \
    -- drivers/hv/ arch/x86/hyperv/ arch/arm64/hyperv/ \
       drivers/iommu/hyperv-iommu.c

Results in Hyper-V code:

  drivers/hv/hv_balloon.c:    ret == -EEXIST | ret == -EAGAIN  (not in table)
  drivers/hv/mshv_eventfd.c:  ret == -EAGAIN                    (not in table)
  drivers/hv/connection.c:    ret == -ETIMEDOUT                 (not in table)
  drivers/hv/mshv_vtl_main.c: ret == -EINVAL || ret == -EACCES  (the consumer
                              this patch fixes)

No other in-tree code path inspects -EOPNOTSUPP, -EACCES, -EINVAL or -EIO
from a hypercall result to make a behavioral decision. The remaining
HV_STATUS_* codes that 3817854 mapped to -EIO are therefore left as
-EIO; nothing keys behavior off the distinction today.

Signed-off-by: Hardik Garg <hargar@microsoft.com>
@hargar19 hargar19 marked this pull request as ready for review June 23, 2026 04:09
Copilot AI review requested due to automatic review settings June 23, 2026 04:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Restores semantically meaningful errno mappings for selected Hyper-V hypercall status codes in hv_result_to_errno(), preventing loss of information at call sites that branch on specific error values (e.g., avoiding incorrect escalation when -EIO masked -EINVAL/-EACCES/-EOPNOTSUPP).

Changes:

  • Map HV_STATUS_ACCESS_DENIED and HV_STATUS_OPERATION_DENIED to -EACCES instead of -EIO.
  • Map HV_STATUS_UNKNOWN_PROPERTY and HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE to -EINVAL instead of -EIO.
  • Map HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED to -EOPNOTSUPP and remove duplicate table entries for HV_STATUS_INVALID_LP_INDEX / HV_STATUS_INVALID_REGISTER_VALUE.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@namancse namancse self-requested a review June 23, 2026 06:20
@namancse

namancse commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Last time, with my change, I did not update dev branch, as I think we don't use it much. To make sure openvmm points to updated dev branch, I create tags from main branch itself (as dev and main are same in our case) and then point openvmm to consume these tags. This way we no longer need to raise 2 PRs (1 on main, other on dev). We can sync dev during LTS upgrades. There we anyways reset the dev branch to reflect main branch.

So if it is OK, we can drop these dev PRs workflow.
Whatever you choose, please create tags from main branch itself (dev tag), otherwise we would miss the fixes not propagated to dev branch.

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.

3 participants