It's the seventh straight victory for Kansas City (36-32), who sit 1 1/2 games back of the Tigers for the American League Central lead with a four-game set beginning in Detroit on Monday.
After Hosmer's first-inning, two-run blast gave the Royals another lead, Chicago trimmed it in half in the bottom of the frame with a balk call on James Shields. Manager Ned Yost was ejected after arguing the call.
Perez made it a 5-1 game with his three-run shot in the third, trying Alex Gordon for the team lead in homers with seven.
Jarrod Dyson then scored Mike Moustakas with an RBI single in the fourth. Moustakas was initially ruled out, but the call was overturned on a challenge, putting the Royals up 6-1.
James Shields (8-3) allowed 10 hits and three runs over six innings, but claimed his fifth straight decision.
Holland made the final out with runners on second and third to pick up his league-leading 20th save.